2

I want load the PEM using .net framework (not .netcore)

-----BEGIN ENCRYPTED PRIVATE KEY-----
MIHs........................................................CAAw
DAYI........................................................gZAf
Y/Iu........................................................X7DZ
ZKoE........................................................OYQQ
3ZST........................................................A2E=
-----END ENCRYPTED PRIVATE KEY-----
  • I tried to use the following code using BouncyCastle, but it throw PemException: "problem creating ENCRYPTED private key: Org.BouncyCastle.Crypto.InvalidCipherTextException: pad block corrupted"
 class Passowrd : IPasswordFinder
    {
        private string v;

        public Passowrd(string v)
        {
            this.v = v;
        }

        public char[] GetPassword()
        {
            return v.ToCharArray();
        }
    }

var pemReader = new PemReader(new StringReader(privateKeyText), new Passowrd("PASSWORD"));
var pemObj = pemReader.ReadObject(); // this line throw PemException
  • However, I load the exact same PEM file using .netcore3.1 by the following code:
    var ecdsa = ECDsa.Create();
    ecdsa.ImportEncryptedPkcs8PrivateKey(passSpan, privateKeyBytes, out _);
Paula Mansour
  • 33
  • 1
  • 6
  • Mmmh, I can't reproduce the issue on _.NET Framework 4.7.2_. This error message is e.g. displayed if the password is incorrect or if the `IPasswordFinder` implementation is buggy. Please post your `Passowrd`-Implementation. – Topaco Apr 16 '20 at 08:19
  • Thanks for your help, I've added the password implementation. – Paula Mansour Apr 16 '20 at 09:11
  • The code works for me (.NET Framework 4.7.2). Possibly a typo in the password? Which .NET Framework version are you using? – Topaco Apr 16 '20 at 09:22
  • the password is correct for sure, I'm using the exact same password in the .netcore code and it works. what is the version of "bouncy-castle" which do you use? I'm using – Paula Mansour Apr 16 '20 at 09:27
  • I'm using 1.8.5. If the password for the posted key is really PASSWORD, then I can reproduce the issue. Then there seems to be an issue with this particular key, because with other keys it works. I'll have a look at the key. – Topaco Apr 16 '20 at 09:35
  • For your key/password I can reproduce the issue. For other keys it works. How was your key generated? – Topaco Apr 16 '20 at 09:58
  • it was generated from python and I'm using it as a client. I think it happen because the key was generated by ecdsa. – Paula Mansour Apr 16 '20 at 10:03
  • Never post any secret information on stackoverflow, such as a private key, unless it just an example and not in real use. – President James K. Polk Apr 16 '20 at 19:20
  • yes it's for testing purpose. – Paula Mansour Apr 17 '20 at 13:55

2 Answers2

0

You can read the PEM either using

var pemReader = new Org.BouncyCastle.OpenSsl.PemReader(new StringReader(privateKeyText), new Passowrd("PASSWORD"));

or

var pemReader = new Org.BouncyCastle.Utilities.IO.Pem.PemReader(new StringReader(privateKeyText));

then read content like

var pemObject = pemReader.ReadPemObject();
Fredrick
  • 513
  • 4
  • 17
  • But ReadPemObject doesn't return the KeyPair.... in other words, I want: AsymmetricCipherKeyPair KeyPair = (AsymmetricCipherKeyPair)pemObject .ReadObject(); – Paula Mansour Apr 16 '20 at 07:28
  • similar question: https://stackoverflow.com/questions/52987169/import-of-pkcs8-encrypted-private-key-using-net/61245450#61245450 – Paula Mansour Apr 16 '20 at 08:06
0

The problem seems to be related to the encryption of the key: The key cannot be read with the PemReader if the option -v2prf hmacWithSHA1 is not set when the key is encrypted.

The option -v2prf exists since V1.1.0 and specifies the PRF (pseudo-random function) algorithm used with PKCS#5 v2.0 or the key derivation function PBKDF2.

  • Case 1: Creating a new key

The following two statements create and encrypt the key:

    openssl ecparam -name secp256r1 -genkey -noout -out <out-path>
    openssl pkcs8 -topk8 -v2 aes256 -v2prf hmacWithSHA1 -in <in-path> -out <out-path>  // aes256 as of OpenSSL 1.1.0 inclusive

A key generated in this way can be successfully read with the PemReader. However, if the option -v2prf hmacWithSHA1 is missing, the exception is thrown.

  • Case 2: Fixing an already generated key

The following statement decrypts an already encrypted key:

    openssl pkcs8 -topk8 -nocrypt -in <in-path> -out <out-path>

If the key is subsequently encrypted with the -v2prf hmacWithSHA1 option set (see above), the key can be read successfully with the PemReader. This way I was able to fix the posted key so that it could be read with the PemReader!

A possible (unfortunately only superficial) explanation can be found in the documentation of openssl pkcs8. There it can be read about the -v2prf option:

Some implementations may not support custom PRF algorithms and may require the hmacWithSHA1 option to work.

Interestingly, the critical keys can be read without problems using ECDsa#ImportEncryptedPkcs8PrivateKey from .NET Core 3.x. For a complete explanation a look into the source code would probably be necessary.

Community
  • 1
  • 1
Topaco
  • 40,594
  • 4
  • 35
  • 62