4

I have the following code in C#:

Main Class

X509Certificate2 cert = new X509Certificate2("C:/test.pfx", "hello", X509KeyStorageFlags.Exportable | X509KeyStorageFlags.PersistKeySet);

            Encryption enc = new Encryption();
            string encrypted = enc.Encrypt("hello there", cert);
            string decrypted = enc.Decrypt(encrypted, cert);
            Console.WriteLine("Encrypted Text: " + encrypted);
            Console.WriteLine("Decrypted Text: " + decrypted);

Encryption Class

public string Encrypt(string plainText, X509Certificate2 cert)
{
    RSACryptoServiceProvider publicKey = (RSACryptoServiceProvider)cert.PublicKey.Key;
    byte[] plainBytes = Encoding.UTF8.GetBytes(plainText);
    byte[] encryptedBytes = publicKey.Encrypt(plainBytes, false);
    string encryptedText = encryptedBytes.ToString();
    return encryptedText;
}

public string Decrypt(string encryptedText, X509Certificate2 cert)
{
    RSACryptoServiceProvider privateKey = (RSACryptoServiceProvider)cert.PrivateKey;
    byte[] encryptedBytes = Encoding.UTF8.GetBytes(encryptedText);
    byte[] decryptedBytes = privateKey.Decrypt(encryptedBytes, false);
    string decryptedText = decryptedBytes.ToString();
    return decryptedText;
}

As you can see, in the main class I am importing a certificate. Then I am creating an instance of the Encryption class. Then I pass plaintext to the Encrypt method along with the certificate in order to get the encrypted text. Afterwards, I pass the encrypted text to the Decrypt method to get the plaintext back.

My problem is that the result of printing the encrypted text is System.[]Byte (if I comment out the decryption call). If I do not comment out the decryption call, I get a Cryptographic Exception: Bad Data in the decryption method.

I guess that the encryptedBytes array is not being converted correctly to string. Furthermore, I am not sure if I am forming the RSAEncryptionProvider correctly. How can I solve this please?

Update

I solved one issue. When converting from byte array to string, I had to use Encoding.UTF8.GetString(EncryptedBytes). The problem now is that the decrypt method is giving me another cryptographic exception (he data to be decrypted exceeds the maximum for this modulus of 128 bytes).

Does anybody know why this is happening and how to solve it?

7
  • 1
    Encryption is always done on binary data (although it might look as a string for you) and always produces binary data as output. Why are you expecting any strings? Commented Apr 28, 2013 at 10:26
  • Please don't repeat tags in titles. Commented Apr 28, 2013 at 10:30
  • @Eugene I want to display the text on the screen to see if it really works Commented Apr 28, 2013 at 10:32
  • I solved one issue. When converting from byte array to string, I had to use Encoding.UTF8.GetString(EncryptedBytes). The problem now is that the decrypt method is giving me another cryptographic exception (he data to be decrypted exceeds the maximum for this modulus of 128 bytes.) Commented Apr 28, 2013 at 10:34
  • @Matthew right, you can't encrypt the block larger than the length of the key with RSA. The correct approach is to generate a random symmetric key, encrypt the data using that key, then encrypt the key with RSA and pass the encrypted key and encrypted data together. Commented Apr 28, 2013 at 10:38

2 Answers 2

4

you can use base64 Format to convert type of variable (encryptedText) parameter by replace the functions

public string Encrypt(string plainText, X509Certificate2 cert)
{
    RSACryptoServiceProvider publicKey = (RSACryptoServiceProvider)cert.PublicKey.Key;
    byte[] plainBytes = Encoding.UTF8.GetBytes(plainText);
    byte[] encryptedBytes = publicKey.Encrypt(plainBytes, false);
    string encryptedText = Convert.ToBase64String(encryptedBytes);
    return encryptedText;
}

public string Decrypt(string encryptedText, X509Certificate2 cert)
{
    RSACryptoServiceProvider privateKey = (RSACryptoServiceProvider)cert.PrivateKey;
    byte[] encryptedBytes = Convert.FromBase64String(encryptedText);
    byte[] decryptedBytes = privateKey.Decrypt(encryptedBytes, false);
    string decryptedText = Encoding.UTF8.GetString(decryptedBytes);
    return decryptedText;
}
Sign up to request clarification or add additional context in comments.

Comments

3

Don't treat encrypted data as a string. Encryption algorithms work on binary data, and produce binary data, which cannot be interpreted as a string. It's naive to think that UTF-8 or any other encoding will be able to interpret any given chunk of binary data as a valid character string.

In your case, if you need to output encrypted data to the console for debugging purposes, go ahead with byte[] and dump it in hexadecimal, like this:

for (int i = 0; i < data.Length; i++)
{
    Console.Write(data[i].ToString("X2"));
    Console.Write(" ");
    if ((i+1) % 16 == 0) Console.WriteLine();
}

4 Comments

But how do you use RSA encryption if you want to pass the encrypted byte[] data from Server A (Windows) to another server B running on Linux?
@Legends The operating system you use is irrelevant in respect to how encryption works.
What I wanted to say is, that Matthew said this in a comment: >>I want to display the text on the screen to see if it really works<< So this was his intention, to display the text to see if his enc/dec functions work: But you said binary data cannot be interpreted as string. And this is wrong, or did you mean something else? Like this: var cert = getC(); RSACryptoServiceProvider rsa= (RSACryptoServiceProvider)cert.PublicKey.Key; byte[] cipherData = rsa.Encrypt(Encoding.UTF8.GetBytes(plainData), _onlyValidCerts); return Convert.ToBase64String(cipherData);
@Legends The answer is (a) three years old, (b) accepted. I'm not getting what you are trying to say here. There's like a thousand methods to dump a chunk of binary data to the console. The one in my answer is correct, worked and was accepted by the OP. Feel free to use ToBase64String should you prefer that kind of output.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.