Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reading PEM RSA Public Key Only using Bouncy Castle

I am trying to use C# to read in a .pem file that contains only a RSA public key. I do not have access to the private key information, nor does my application require it. The file myprivatekey.pem file begins with

-----BEGIN PUBLIC KEY----- and ends with -----END PUBLIC KEY-----.

My current code is as follows:

    Org.BouncyCastle.Crypto.AsymmetricCipherKeyPair keyPair;

    using (var reader = File.OpenText(@"c:\keys\myprivatekey.pem"))
        keyPair = (Org.BouncyCastle.Crypto.AsymmetricCipherKeyPair)new Org.BouncyCastle.OpenSsl.PemReader(reader).ReadObject();

However the code throws an InvalidCastException with the message

Unable to cast object of type 'Org.BouncyCastle.Crypto.Parameters.DsaPublicKeyParameters' to type 'Org.BouncyCastle.Crypto.AsymmetricCipherKeyPair'.

How can I use Bouncy Castle's PemReader to read only a public key, when no private key information is available?

like image 712
cytinus Avatar asked Jul 05 '12 14:07

cytinus


People also ask

How do I generate a public and private key from a PEM file?

pem file is saved. Right click on the location and click on select Git Bash Here as shown in the screenshot. Execute the below command in the console to extract public key. The public key will be extracted in the same location as pem file & the format of the key is '.

Is the public key in PEM file?

Privacy Enhanced Mail (PEM) files are a type of Public Key Infrastructure (PKI) file used for keys and certificates. PEM, initially invented to make e-mail secure, is now an Internet security standard.

Can we get private key from PEM file?

PEM is a base-64 encoding mechanism of a DER certificate.PEM can also encode other kinds of data, such as public/private keys and certificate requests.


2 Answers

The following code will read a public key from a given filename. The exception handling should be changed for any production code. This method returns an AsymetricKeyParameter:

public Org.BouncyCastle.Crypto.AsymmetricKeyParameter ReadAsymmetricKeyParameter(string pemFilename)
{
    var fileStream = System.IO.File.OpenText(pemFilename);
    var pemReader = new Org.BouncyCastle.OpenSsl.PemReader(fileStream);
    var KeyParameter = (Org.BouncyCastle.Crypto.AsymmetricKeyParameter)pemReader.ReadObject();
    return KeyParameter;
}
like image 82
cytinus Avatar answered Sep 20 '22 13:09

cytinus


Here's a possible solution that reads both public and private PEM files into RSACryptoServiceProvider:

public class PemReaderB
{
    public static RSACryptoServiceProvider GetRSAProviderFromPem(String pemstr)
    {
        CspParameters cspParameters = new CspParameters();
        cspParameters.KeyContainerName = "MyKeyContainer";
        RSACryptoServiceProvider rsaKey = new RSACryptoServiceProvider(cspParameters);

        Func<RSACryptoServiceProvider, RsaKeyParameters, RSACryptoServiceProvider> MakePublicRCSP = (RSACryptoServiceProvider rcsp, RsaKeyParameters rkp) =>
        {
            RSAParameters rsaParameters = DotNetUtilities.ToRSAParameters(rkp);
            rcsp.ImportParameters(rsaParameters);
            return rsaKey;
        };

        Func<RSACryptoServiceProvider, RsaPrivateCrtKeyParameters, RSACryptoServiceProvider> MakePrivateRCSP = (RSACryptoServiceProvider rcsp, RsaPrivateCrtKeyParameters rkp) =>
        {
            RSAParameters rsaParameters = DotNetUtilities.ToRSAParameters(rkp);
            rcsp.ImportParameters(rsaParameters);
            return rsaKey;
        };

        PemReader reader = new PemReader(new StringReader(pemstr));
        object kp = reader.ReadObject();

        // If object has Private/Public property, we have a Private PEM
        return (kp.GetType().GetProperty("Private") != null) ? MakePrivateRCSP(rsaKey, (RsaPrivateCrtKeyParameters)(((AsymmetricCipherKeyPair)kp).Private)) : MakePublicRCSP(rsaKey, (RsaKeyParameters)kp);
    }

    public static RSACryptoServiceProvider GetRSAProviderFromPemFile(String pemfile)
    {
        return GetRSAProviderFromPem(File.ReadAllText(pemfile).Trim());
    }
}

Hope this helps someone.

like image 35
Bryan Jyh Herng Chong Avatar answered Sep 22 '22 13:09

Bryan Jyh Herng Chong