C# RSA Decrypt Using Private Key

cencryptionprivatersa

I've been searching but I can't seem to find a simple way of decrypting using RSA.

I have generated a public and private key, they are stored in two separate files and are in the XML format. I have no problem associating the public key to the RSACryptoServiceProvider object using FromXmlString, and then encrypting a string. My confusion comes when trying to decrypt an encrypted string. I'm not sure how I associate the private key data with the RSACryptoServiceProvider so that I can use the Decrypt function.

Any help would be appreciated.

EDIT:

The format of the public and private key is XML generated by the RSACryptoServiceProvider object, which I just put into a file:

<RSAKeyValue><Modulus>vS7Y5up+6kHMx7hQjKA6sKlIVASaw  ... etc ...

I load the public key using this code:

StreamReader sr = new StreamReader(HttpContext.Current.Server.MapPath("public.key"));
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
rsa.FromXmlString(sr.ReadToEnd().ToString());

I currently haven't tried anything with the private key yet, since I'm not sure where to start.

Best Answer

I don't know your situation but I would suggest that you store you key information in a KeyContainer. If you do this you can access the keyContainer by name and can do something like this.

// retrieves the maximum number of characters that can be decrypted at once
private int getMaxBlockSize(int keySize){
    int max = ((int)(keysize/8/3) )* 4
    if (keySize / 8 mod 3 != 0){
        max += 4
    }
    return max;
}

public string decrypt(string msg, string containerName){
    CspParameters params = new CspParameters();
    params.KeyContainerName = containerName;
    RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(params);
    StringBuilder decryptedMsg = new StringBuilder();
    int maxDecryptSize = getMaxBlockSize(rsa.KeySize);
    int iterationCount = Math.Floor(msg.length / maxDecryptSize)
    for(int i=0; i<iterationCount; i++){
        int start = i * maxDecryptSize;
        int blkSize = Math.min(start + maxDecryptSize, msg.Length);
        Byte[] msgBytes = System.Convert.FromBase64String(msg.Substring(start, blkSize));

        decryptedMsg.Append(System.Text.Encoding.Unicode.GetString(RSAProvider.Decrypt(msgBytes, false));
    }
    return decryptedMsg.ToString();
}

I haven't tested this out so there might be a bug in here but the you get the idea.