Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

parsePkcs12 generating an incorrect private key #110

Open
pedroserretti opened this issue Mar 5, 2024 · 3 comments
Open

parsePkcs12 generating an incorrect private key #110

pedroserretti opened this issue Mar 5, 2024 · 3 comments

Comments

@pedroserretti
Copy link

pedroserretti commented Mar 5, 2024

Hi!
I'm doing a function to sign my XML's by my .pfx file, so i need to parsePkcs12 to get private key.

I've already tested with one certificate and it does successfully, but when i tested with another certificate, my XML wasn't signing anymore.

So i generated a PEM file from my PFX file to compare. When i analyzed, i realized that my PEM generated from parsePkcs12 was different of my PEM file.

Here's an example of what's coming for me:

Initials from my PEM file:

-----BEGIN PRIVATE KEY-----
MIIEvQIBADAN... (omitted)

... WiCjgGs9A= (omitted)
-----END PRIVATE KEY-----

Initials from PEM generated by parsePkcs12:

-----BEGIN PRIVATE KEY-----
MIIEzAIBADANBgkqh... (omitted)

...8xBAMCABA= (omitted)
-----END PRIVATE KEY-----

Can anyone help me please??
Thanks!

@mposch-Z
Copy link

mposch-Z commented Jan 6, 2025

I am also facing a similar issue for a .pfx file. The parsePkcs12 method is returning an invalid private key, it has an additional unexpected 20 characters at the end of the sequence.
For instance, converting a PFX file via the following command yields a different result than when using Pkcs12Utils.parsePkcs12() method:

openssl pkcs12 -in filename.pfx -out cert.pem -nodes

Note the PFX file contains private key and numerous certificates.

Update
In my case, it seems that the parsePkcs12 method is including optional attributes that are encrypted along with the private key information.
This seems to be valid ASN.1 syntax per RFC 5208 section 5 :
https://www.rfc-editor.org/rfc/rfc5208.html#section-5

@mposch-Z
Copy link

mposch-Z commented Jan 9, 2025

Updating my above comment, for reproduction export a PFX from Windows.
The parsePkcs12 method returns a list of PEM certificates and if the 1st certificate (the private key) is utilized AS IS the additional ATTRIBUTES (from RFC 5208) of the PrivateKeyInfo struct is contained in this output. If you isolate the first element in the result of parsePkcs12 and use in the generatePkcs12 function then the result of that method can be parsed again and yield the private key as I believe you are expecting:

List<String> pems = Pkcs12Utils.parsePkcs12(
      buffer,
      password: password,
    );

    //Isolate the private key to be used when regenerating the pkcs12. Using generatePkcs12 will not add the PrivateKeyInfo optional attribute to the private key
    //https://www.rfc-editor.org/rfc/rfc5208  ATTRIBUTES are appended to private key after parsePkcs12 for some reason
    String privateKey = pems.first;

    //Remove private key to regenerate these certs without additional attribute... Pkcs12Util always puts the private key first in the list. Pkcs12 certs always contain a private key
    pems.remove(pems.first);

    Uint8List certWithCorrectedPrivateKey = Pkcs12Utils.generatePkcs12(privateKey, pems, password: password); //Private key now excludes the additional ASN.1 attribute, issue in underlying package parsePkcs12 impl?
    List<String> newPems = Pkcs12Utils.parsePkcs12(
      certWithCorrectedPrivateKey,
      password: password,
    );

Admittedly I'm in the middle of reverse engineering my understanding of all of this, but are there other utils/methods intended to be used to obtain the PEM representation of the private key?

@mposch-Z
Copy link

Just wanted to update what worked for me in the end. Essentially reconstructing the private key and converting back to PEM removed the optional additional sequence that is appended to the private key info:

List<String> pems = Pkcs12Utils.parsePkcs12(
        buffer,
  password: password,
);

//Isolate private key contents from PEM
RSAPrivateKey key = CryptoUtils.rsaPrivateKeyFromPem(pems.first);
String privateKeyPem = CryptoUtils.encodeRSAPrivateKeyToPem(key);

//Remove previous private key PEM contents, as it can contain additional attributes appended to the private key
pems.remove(pems.first);

String certData = "$privateKeyPem\n${pems.join("\n")}";
// proceed to parse private key

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants