4
votes

I am trying to read an RSA private key into .Net using BouncyCastle to test data I have previously encrypted. The encrypted data is working fine using the public key and Bouncy Castle and I have also used the same private key as below (which is DER format) to successfully decrypt my data in a PHP application but I don't know why I can't create the private key in .Net to do the same thing:

byte[] privatekey = File.ReadAllBytes(@"C:\Users\Luke\privkey.der");
var rsaKeyParameters = (RsaKeyParameters)PrivateKeyFactory.CreateKey(privatekey);

The second line throws an exception:

"unknown object in factory: DerInteger\r\nParameter name: obj"

I also tried using a stream instead of a byte array and the same error occurs. The key pair was created using OpenSSL and as mentioned, decryption works in PHP using openssl_private_decrypt() and the same key as in the .Net code. I also tried a PEM format of the same key and that also didn't work (but I don't think BC supports PEM directly anyway)

Has anyone done this before? Thanks

1
Could you show us the DER format? If it is a text file then it isn't DER, but a PEM encoding of the DER. In that case you first need to remove the ASCII armour (as PEM also is called).Maarten Bodewes
It is in binary format so it obviously won't paste into here. I used an online javascript checker and it was happy with the key and showed all the contents.Lukos
I understand Lukos, but if we don't know the format of the private key then we cannot see what is wrong, unless we encountered exactly this issue ourselves (or possibly by going through the source code). If this forum does not work, you may want to give the Bouncy Castle mailinglist a try...Maarten Bodewes
I'm not sure what you are asking since I cannot paste the binary of the file into a text editor. It was generated using openssl genrsa -out privkey.der -outform der 2048. The decryption that works in PHP then had the der key converted to pem, also using openssl.Lukos

1 Answers

8
votes

The problem was that I had assumed PublicKeyFactory and PrivateKeyFactory were complimentary since they are in the same namespace. They are not!

To decode the private key, I needed the following alternative code:

var privKeyObj = Asn1Object.FromStream(privatekey);
var privStruct = new RsaPrivateKeyStructure((Asn1Sequence)privKeyObj);

// Conversion from BouncyCastle to .Net framework types
var rsaParameters = new RSAParameters();
rsaParameters.Modulus = privStruct.Modulus.ToByteArrayUnsigned();
rsaParameters.Exponent = privStruct.PublicExponent.ToByteArrayUnsigned();
rsaParameters.D = privStruct.PrivateExponent.ToByteArrayUnsigned();
rsaParameters.P = privStruct.Prime1.ToByteArrayUnsigned();
rsaParameters.Q = privStruct.Prime2.ToByteArrayUnsigned();
rsaParameters.DP = privStruct.Exponent1.ToByteArrayUnsigned();
rsaParameters.DQ = privStruct.Exponent2.ToByteArrayUnsigned();
rsaParameters.InverseQ = privStruct.Coefficient.ToByteArrayUnsigned();
var rsa = new RSACryptoServiceProvider();
rsa.ImportParameters(rsaParameters);
return Encoding.UTF8.GetString(rsa.Decrypt(Convert.FromBase64String(ciphertext), true));

A BIG thankyou to owlstead for their help.