Will
Will

Reputation: 989

C# RSA Decrypt Using Private Key

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.

Upvotes: 4

Views: 13056

Answers (2)

Ritesh Saraswat
Ritesh Saraswat

Reputation: 21

if you have private key in text format like given below -----BEGIN RSA PRIVATE KEY----- text.... -----END RSA PRIVATE KEY-----

    public string RsaDecryptWithPrivate(string base64Input, string privateKey)
    {
        var bytesToDecrypt = Convert.FromBase64String(base64Input);

        AsymmetricCipherKeyPair keyPair;
        var decryptEngine = new Pkcs1Encoding(new RsaEngine());

        using (var txtreader = new StringReader(privateKey))
        {
            keyPair = (AsymmetricCipherKeyPair)new PemReader(txtreader).ReadObject();//fetch key pair from text file 

            decryptEngine.Init(false, keyPair.Private);
        }

        var decrypted = Encoding.UTF8.GetString(decryptEngine.ProcessBlock(bytesToDecrypt, 0, bytesToDecrypt.Length));
        return decrypted;
    }

Upvotes: 2

Nimnam1
Nimnam1

Reputation: 513

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.

Upvotes: 1

Related Questions