C# RSACryptoServiceProvider ToXmlString()/FromXmlString()

16,589

Solution 1

This has nothing to do with your public/private key handling (I think that part looks OK, the file I/O can be done easier though).

But your way of transporting the encrypted data as a string is not suitable for "round-trip" . Use a Base64 encoding instead.

You should be able to see this in the debugger: make a note of the length and the first bytes of encryptedData and this should match d in the Decrypt method.

Solution 2

The answer to your second edit is no, base64 strings uses only alpha numeric characters and "+", "/" and "=".

Learn more here

Share:
16,589

Related videos on Youtube

user441521
Author by

user441521

Updated on July 11, 2022

Comments

  • user441521
    user441521 almost 2 years

    EDIT2: Seems Convert.FromBase64String is my savior. Does anyone know if a comma would every be in such a string? I'm doing basic csv parsing. If it is I can always use quotes (but can quotes ever be in a string like this too I guess) but this is just a small project for myself so just easier to parse by splitting by ','.

    EDIT: OK so it would seem my issue is when I convert the encrypted bytes to a string, then convert that string back to bytes to be decrypted. How could I do this because I want to actually store the encrypted string somewhere and be able to decrypt that string.

    I'm trying to save the public key (and private just for testing) to an xml file so that I can read the same one in later, but getting "Bad data" error when trying to decrypt. Can anyone see what I'm doing wrong?

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Security.Cryptography;
    using System.IO;
    
    namespace EncryptionTest
    {
    class Program
    {
        static void Main(string[] args)
        {
            UnicodeEncoding ByteConverter = new UnicodeEncoding();
    
            byte[] dataToEncrypt = ByteConverter.GetBytes("Test data");
    
            WriteRSAInfoToFile();
    
            string enc = Encrypt(dataToEncrypt);
    
            enc = Decrypt(enc);
        }
    
        static void WriteRSAInfoToFile()
        {
            RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
            TextWriter writer = new StreamWriter("C:\\publicKey.xml");
            string publicKey = RSA.ToXmlString(false);
            writer.Write(publicKey);
            writer.Close();
    
            writer = new StreamWriter("C:\\privateKey.xml");
            string privateKey = RSA.ToXmlString(true);
            writer.Write(privateKey);
            writer.Close();
        }
    
        static string Encrypt(byte[] data)
        {
            UnicodeEncoding ByteConverter = new UnicodeEncoding();
            RSACryptoServiceProvider encrypt = new RSACryptoServiceProvider();
            TextReader reader = new StreamReader("C:\\publicKey.xml");
            string publicKey = reader.ReadToEnd();
            reader.Close();
    
            encrypt.FromXmlString(publicKey);
    
            byte[] encryptedData = encrypt.Encrypt(data, false);
    
            return ByteConverter.GetString(encryptedData);
        }
    
        static string Decrypt(string data)
        {
            UnicodeEncoding ByteConverter = new UnicodeEncoding();
            RSACryptoServiceProvider decrypt = new RSACryptoServiceProvider();
            TextReader reader = new StreamReader("C:\\privateKey.xml");
            string privateKey = reader.ReadToEnd();
            reader.Close();
    
            decrypt.FromXmlString(privateKey);
    
            byte[] d = ByteConverter.GetBytes(data);
            byte[] decryptedData = decrypt.Decrypt(d, false);       // ERROR: bad data
    
            return ByteConverter.GetString(decryptedData);
        }
    }
    

    }

  • gmaran23
    gmaran23 over 11 years
    Don't Roundtrip Ciphertext Via a String Encoding - blogs.msdn.com/b/shawnfa/archive/2005/11/10/491431.aspx something worth mentioning here.