Re: Public Key Encryption with RSACryptoServiceProvider

From: AlBruAn (albruan_at_hotmail.com.(donotspam))
Date: 06/25/04


Date: Fri, 25 Jun 2004 11:55:01 -0700


"Pieter Philippaerts" wrote:

> "AlBruAn" <AlBruAn@discussions.microsoft.com> wrote in message
> > I'm attempting to use the RSACryptoServiceProvider class to encrypt some
> licensing information I'm storing in SQL Server, but I'm encountering a "Bad
> Data" CryptographicException when I try decrypting the data and wonder how I
> can get around this issue. I'm not storing any information in SQL Server
> until I can get the mechanics of encryption working properly. Anyway...
> > I've generated a pair of public and private keys using
> RSACryptoServiceProvider's ToXml function, passing false and true arguments,
> respectively, to it. I then persist these keys to the root directory of my
> C: drive using an XmlTextWriter.
> > When it's time to encrypt a license number, I create a new instance of the
> RSACryptoServiceProvider object and read in the public key using its FromXml
> function. I then call the Encrypt function, passing it the license number
> and specifying no OAEP padding. My final step is to persist the encrypted
> values to a separate file in the root directory of my C: drive.
>
> From your description, there doesn't seem to be an abvious error. Could you
> post the source code you're using so we can take a closer look?
>
> > Even tho' I'm using the string "123" as my "license number" and using the
> same
> > public key, I'm getting different values for the encrypted "license
> number".
>
> This is normal; whenever you encrypt something, the RSACryptoServiceProvider
> will add a special padding to your data to make sure the length is equal to
> the modulus size of your public key. This padding consists mostly of random
> bytes, hence the difference.
>
> Regards,
> Pieter Philippaerts
>
>
It's rather long, but here is the class I wrote to try using the RSACryptoServiceProvider:

using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using System.Xml;

namespace TryRSA
{
        class EncryptDecrypt
        {
                public void DoThis(string Msg, bool Encode)
                {
                        try
                        {
                                UnicodeEncoding ByteConverter = new UnicodeEncoding();
                                byte[] dataToEncrypt = ByteConverter.GetBytes("Data to Encrypt");
                                byte[] encryptedData;
                                byte[] decryptedData;
            
                                //Create a new instance of RSACryptoServiceProvider to generate
                                //public and private key data.
                                RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(1024);

                                // Generate and persist the private and/or public keys
                                GenKeys(RSA, Encode);

                                if (Encode == true)
                                {
                                        encryptedData = RSAEncrypt(dataToEncrypt, false);
                                        string encoded;
                                        StreamWriter sw = new StreamWriter("C:\\Encrypted.dat");
                                        UTF8Encoding utf8 = new UTF8Encoding();
                                        encoded = utf8.GetString(encryptedData);
                                        sw.WriteLine(encoded);
                                        sw.Close();
                                }
                                else
                                {
                                        StreamReader sr = new StreamReader("C:\\Encrypted.dat");
                                        string encoded = sr.ReadLine();
                                        sr.Close();
                                        UTF8Encoding utf8 = new UTF8Encoding();
                                        encryptedData = utf8.GetBytes(encoded);
                                        decryptedData = RSADecrypt(encryptedData, false);
                                        Console.WriteLine("Decrypted plaintext: {0}", ByteConverter.GetString(decryptedData));
                                }
                        }
                        catch(ArgumentNullException)
                        {
                                Console.WriteLine("Encryption failed.");
                        }
                }

                static public byte[] RSAEncrypt(byte[] DataToEncrypt, bool DoOAEPPadding)
                {
                        try
                        {
                                RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
                                RSA.FromXmlString(publicKey);
                                return RSA.Encrypt(DataToEncrypt, DoOAEPPadding);
                        }
                        catch(CryptographicException e)
                        {
                                Console.WriteLine(e.Message);
                                return null;
                        }
                }

                static public byte[] RSADecrypt(byte[] DataToDecrypt, bool DoOAEPPadding)
                {
                        try
                        {
                                RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
                                RSA.FromXmlString(privateKey);
                                return RSA.Decrypt(DataToDecrypt, DoOAEPPadding);
                        }
                        catch(CryptographicException e)
                        {
                                Console.WriteLine(e.ToString());
                                return null;
                        }
                }

                static private string _publicKey;
                static private string publicKey
                {
                        get { return _publicKey; }
                        set { _publicKey = value; }
                }
                static private string _privateKey;
                static private string privateKey
                {
                        get { return _privateKey; }
                        set { _privateKey = value; }
                }

                public void GenKeys(RSACryptoServiceProvider RSA, bool Encode)
                {
                        string publicKeyFileName = "C:\\public.key";
                        string privateKeyFileName = "C:\\private.key";

                        if (Encode == true)
                        {
                                // Public key
                                if (!File.Exists(publicKeyFileName))
                                {
                                        publicKey = RSA.ToXmlString(false);

                                        FileStream FileWriter = new FileStream(publicKeyFileName, FileMode.Create);
                                        XmlTextWriter XmlWriter = new XmlTextWriter(FileWriter, System.Text.Encoding.UTF8);

                                        XmlWriter.WriteRaw(publicKey);
                                        XmlWriter.Close();
                                        FileWriter.Close();
                                }
                                else
                                {
                                        FileStream FileReader = new FileStream(publicKeyFileName, FileMode.Open);
                                        XmlTextReader XmlReader = new XmlTextReader(FileReader);
                                        XmlDocument XmlDoc = new XmlDocument();

                                        XmlDoc.Load(XmlReader);
                                        publicKey = XmlDoc.InnerXml;
                                        XmlReader.Close();
                                        FileReader.Close();
                                }
                        }
                        else
                        {
                                // Private key
                                if (!File.Exists(privateKeyFileName))
                                {
                                        privateKey = RSA.ToXmlString(true);

                                        FileStream FileWriter = new FileStream(privateKeyFileName, FileMode.Create);
                                        XmlTextWriter XmlWriter = new XmlTextWriter(FileWriter, System.Text.Encoding.UTF8);

                                        XmlWriter.WriteRaw(privateKey);
                                        XmlWriter.Close();
                                        FileWriter.Close();
                                }
                                else
                                {
                                        FileStream FileReader = new FileStream(privateKeyFileName, FileMode.Open);
                                        XmlTextReader XmlReader = new XmlTextReader(FileReader);
                                        XmlDocument XmlDoc = new XmlDocument();

                                        XmlDoc.Load(XmlReader);
                                        privateKey = XmlDoc.InnerXml;
                                        XmlReader.Close();
                                        FileReader.Close();
                                }
                        }
                }
        }
}



Relevant Pages

  • Re: Public Key Encryption with RSACryptoServiceProvider
    ... > When it's time to encrypt a license number, I create a new instance of the ... RSACryptoServiceProvider object and read in the public key using its FromXml ... I then call the Encrypt function, passing it the license number ...
    (microsoft.public.dotnet.security)
  • Re: Use my your own HashAlgorithm Class
    ... Rather than use the EncryptValue / DecryptValue methods (which RSACryptoServiceProvider doesn't support), ... the Encrypt and Decrypt methods. ... >> doesn't know about your new algorithm. ... But CAPI doesn't work with OIDs directly, ...
    (microsoft.public.dotnet.security)
  • RSA Encryption: Saving keys as files, and size of encrypted data
    ... Could I ask for some help with RSACryptoServiceProvider class. ... files, and the other 2 apps encrypt and decrypt, using those xml strings. ... Dim RSA As RSACryptoServiceProvider = New ... Dim PubKey as string = RSA.ToXmlString ...
    (microsoft.public.dotnet.security)
  • Re: How to decrypt with an RSA public key (at all)
    ... then have the server encrypt the license with the client's ... public key, then the client decrypts it with it's private key. ...
    (microsoft.public.dotnet.framework.aspnet.security)
  • Strong encryption with RSACryptoServiceProvider..?
    ... Does anyone know how to encrypt more than 16 bytes with the ... RSACryptoServiceProvider on Windows 98? ... Byte array is too large. ... I suspect that the RSACryptoServiceProvider uses the Microsoft Base CSP on ...
    (microsoft.public.dotnet.security)