I want to encrypt some data with my private RSA key and then decrypt it on the client machine with the public key. As far as I know, this is a normal way of using RSA.
However, as far as I see, there is a problem with this in RSACryptoServiceProvider of the .NET Framework. While the decryption works fine when you provide both the public and the private key to the RSACryptoServiceProvider, it doesn't when you only provide only the public key. In this case, I get a padding error:
Error occurred while decoding OAEP padding.
at System.Security.Cryptography.RSACryptoServiceProvider.DecryptKey(SafeKeyHandle pKeyContext, Byte[] pbEncryptedKey, Int32 cbEncryptedKey, Boolean fOAEP, ObjectHandleOnStack ohRetDecryptedKey)
at System.Security.Cryptography.RSACryptoServiceProvider.Decrypt(Byte[] rgb, Boolean fOAEP)
Notes :
fOAEP set to true.Am I missing sth? I don't see any setting for the padding that I can change.
Definitely, I can't send my private key to the client machine...
Should I try another library like Bouncy Castle ?
I have found this question too, but there is no clear solution and, according to the author, his final solution was to use code from this article. However, I would prefer to use the .NET Framework's code if possible and I don't understand why my decryption fails.
Also, I don't think that my data is so long that this answer is of any relevance.
Perhaps I could use SignHash()/VerifyHash() but I think those calculate the hash from the data before encrypting it while I already have a hash computed and I just need to encrypt it. Using SignHash() will limit the variety of hashing algorithms that I could use, so it may be better to avoid it.
A signature generation contains 3 distinct parts. First the hash is calculated, then padding is added and finally RSA performs modular exponentiation (possibly helped by using the Chinese Remainder Theorem to speed things up).
All three of these parts of signature generation are part of the signature algorithm. It is wrong to think of signature generation as three distinct parts. It is particularly wrong to think of RSA signature generation as using RSA encryption. RSA encryption uses it's own padding mechanisms which are incompatible with the ones used for signing.
This is all very well explained in the PKCS#1 v2.2 standard.
The main mathematical operation in each primitive is exponentiation, as in the encryption and decryption primitives of Section 5.1. RSASP1 and RSAVP1 are the same as RSADP and RSAEP except for the names of their input and output arguments; they are distinguished as they are intended for different purposes.
So even the standard very explicitly uses different functions, even though they perform essentially the same mathematical operation.
The final outcome is simply this: you must use the RSACryptoServiceProvider class for PKCS#1 v1.5 compatible signatures, or the Bouncy Castle C# libraries to use the newer RSA PSS signature scheme. If you want to create a signature for a pre-calculated hash, use SignHash, although - as you mentioned - this function is currently restricted to SHA-1 or MD5.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With