Search code examples
c#encryptionserializationrsapublic-key

Deserialize RSA public and private key C#


As a part of my project I have to encrypt some text with RSA and I have got a public key from another company. The public key looks like this:

var publicKey="MIGfMA0GCSq2GSIb3DQEBAQUAA4GNADCBiQKBgQCgFGVfrY4jQSoZQWWygZ83roKXWD4YeT2x2p41dGkPixe73rT2IW04glatgN2vgoZsoHuOPqah5and6kAmK2ujmCHu6D1auJhE2tXP+yLkpSiYMQucDKmCsWXlC5K7OSL77TXXcfvTvyZcjObEz6LIBRzs6+FqpFbUO9SJEfh6wIDAQAB" 

The problem is that I don't know what is its format and how to deserialize it to RSAParameters. Other examples on the Internet have used XML serialization. The key is created by Java.

Then I also want to know how to deserialize its related private key which I don't have access to any sample of it right now.

Update :

Here is part of my code :

var pk = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCiiTx4F35eWP10AFMAo8MLhCKq2ryKFG9PKKWeMLQuwMSdiQq347BkMYA+Q+YscScf7weUSTk9BHVNNfTchDwzjQrIoz6TZGggqD+ufin1Ccy0Sp6QeBMnIB89JsdzQGpVcsoTxk53grW0nYY8D+rlFvBwFicKe/tmVPVMYsEyFwIDAQAB";

...

public static RSACryptoServiceProvider ImportPublicKey(string pem)
{
    //var newPem = "-----BEGIN PUBLIC KEY-----\n" + pem + "-----END PUBLIC KEY-----";
    Org.BouncyCastle.OpenSsl.PemReader pr = new Org.BouncyCastle.OpenSsl.PemReader(new StringReader(Pem));
    Org.BouncyCastle.Crypto.AsymmetricKeyParameter publicKey = (Org.BouncyCastle.Crypto.AsymmetricKeyParameter)pr.ReadObject();
    RSAParameters rsaParams = Org.BouncyCastle.Security.DotNetUtilities.ToRSAParameters((Org.BouncyCastle.Crypto.Parameters.RsaKeyParameters)publicKey);

    RSACryptoServiceProvider csp = new RSACryptoServiceProvider();// cspParams);
    csp.ImportParameters(rsaParams);
    return csp;
}

Solution

  • The posted key is a PEM encoded public key in X.509 (SPKI) format, but without header (-----BEGIN PUBLIC KEY-----) and footer (-----END PUBLIC KEY-----). This can be easily verified with an ASN.1 parser, e.g. here.

    The import of such a key depends on the .NET version. .NET Core offers from v3.0 on methods that directly support the import of PKCS#1, PKCS#8 and X.509 keys, e.g. RSA.ImportSubjectPublicKeyInfo for the latter. This option is not available for .NET Framework, but BouncyCastle offers a similarly comfortable solution.

    Here (see ImportPublicKey method) is an example that imports a PEM encoded public key in X.509 (SPKI) format using BouncyCastle. However, the PemReader used there expects the complete PEM data, including header and footer, both separated from the body by line breaks. Therefore, when using the public keys posted here, header and footer must be added accordingly, e.g:

    using System.IO;
    using System.Security.Cryptography;
    using Org.BouncyCastle.Crypto;
    using Org.BouncyCastle.Crypto.Parameters;
    using Org.BouncyCastle.OpenSsl;
    using Org.BouncyCastle.Security;
    ...
    // from: https://gist.github.com/valep27/4a720c25b35fff83fbf872516f847863
    public static RSACryptoServiceProvider ImportPublicKey(string pemBody)
    {
        var pem = "-----BEGIN PUBLIC KEY-----\n" + pemBody + "\n-----END PUBLIC KEY-----";      // Add header and footer
        PemReader pr = new PemReader(new StringReader(pem));
        AsymmetricKeyParameter publicKey = (AsymmetricKeyParameter)pr.ReadObject();
        RSAParameters rsaParams = DotNetUtilities.ToRSAParameters((RsaKeyParameters)publicKey);
    
        RSACryptoServiceProvider csp = new RSACryptoServiceProvider();// cspParams);
        csp.ImportParameters(rsaParams);
        return csp;
    }