I know the main answer I am likely to get is why the hell would you want to do that?!
Unfortunately despite my protests I have to do it, even though I know it makes
Having looked at some of the information on RSA encryption modes, it would appear that PKCS#1 v1.5 (which you're using, because you're calling Decrypt(..., false)
)
"...can operate on messages of length up to k - 11 octets (k is the octet length of the RSA modulus)"
(RFC 3447, emphasis mine).
Based on the error message, which indicates that your key is 128 bytes, that means that you can't perform RSA (en|de)cryption using PKCS#1 v1.5 on a message with more than 128 - 11 = 117 bytes.
Instead of encrypting your message directly using RSA, you should be using a symmetric algorithm to encrypt the body of the message, and encrypt only the symmetric encryption key using RSA. Only if your message is reasonably short (i.e. below 117 bytes for your key size) should you consider encrypting the message directly with RSA.
I have added the following, assuming that your input is Base64 encoded as you indicate in your comment below:
public string DecryptUsingPublic(string dataEncryptedBase64, string publicKey)
{
if (dataEncryptedBase64 == null) throw new ArgumentNullException("dataEncryptedBase64");
if (publicKey == null) throw new ArgumentNullException("publicKey");
try
{
RSAParameters _publicKey = LoadRsaPublicKey(publicKey, false);
RSACryptoServiceProvider rsa = InitRSAProvider(_publicKey);
byte[] bytes = Convert.FromBase64String(dataEncryptedBase64);
byte[] decryptedBytes = rsa.Decrypt(bytes, false);
// I assume here that the decrypted data is intended to be a
// human-readable string, and that it was UTF8 encoded.
return Encoding.UTF8.GetString(decryptedBytes);
}
catch
{
return null;
}
}
RSA is not meant to encrypt arbitrary data, even less arbitrary data length (like @Iridium already told you). The limit depends on the padding used and using the padding is very important (enough that MS won't let you call EncryptValue
and DecryptValue
directly).
The right way to do this is to encrypt your string using a symmetric cipher (like AES) then encrypt the secret key using the RSA public key.
The other party will be able to decrypt the secret (AES) key using the RSA private key. Then using the key decrypt your string.
I have an old (but still up to date) blog entry on the subject that includes source code (C#).
RSA is built into .NET: System.Security.Cryptography.RSA
.
Encrypting using the public key and decrypting with the private key is one of the most common things people do with asymmetric algorithms, it allows anybody to send you something securely.
If you do it the other way: encrypt using the private key, and decrypt with the public key then it proves the message was sent by the holder of the private key. But because anyone presumably can get hold of the public key, people don't tend to encrypt the whole message, they instead just sign a hash of the data using the private key. Hence RSACryptoServiceProvider
has Sign__
and Verify__
methods to do just that.
Still, there are Encrypt/Decrypt
methods if your partner insists.
Saying that, I've found the Microsoft crypto classes a bit tricky to deal with and lacking in certain areas and much prefer the Bouncy Castle libraries.