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?
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 '.
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.
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.
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;
}
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With