Closed irririki closed 2 years ago
Your first EC key seems to have wrong optional public key field:
SEQUENCE {
INTEGER 0
SEQUENCE {
OBJECT IDENTIFIER ecPublicKey (1 2 840 10045 2 1)
OBJECT IDENTIFIER prime256v1 (1 2 840 10045 3 1 7)
}
OCTET STRING, encapsulates {
SEQUENCE {
INTEGER 1
OCTET STRING
B7 1E 78 BB 45 80 72 6D C8 5C 86 E6 B0 34 24 F1
2B 54 77 9D 05 2D FD BB C9 C8 B1 30 EB F9 44 7B
[1] {
BIT STRING
'0000000000000000'B // ****** WRONG PUBLIC KEY
}
}
}
}
Please use following for workaround:
const keypair = KEYUTIL.generateKeypair("EC", "secp256r1");
const prmPem = KEYUTIL.getPEM(keypair.prvKeyObj, "PKCS8PRV");
This will be much easier and working fine.
The first method is a valid route that leads to wrongly generated PEM using KEYUTIL.getPEM. I am aware of the second method which produces the correct result as mentioned in the description. But should method 1 be fixed since it's there?
It was fixed in the 10.5.14 release today.
When a public key is not provided as you do, optional public key field in a PKCS#8 will be omitted after this fix.
const keypair = ecdsa.generateKeyPairHex();
const prvhex = keypair.ecprvhex;
const prvObj = new KJUR.crypto.ECDSA({'curve': 'secp256r1', 'prv': prvhex});
const prvPem = KEYUTIL.getPEM(prvObj, "PKCS8PRV");
node: v16.13.2 jsrsasign: "^10.5.13"
I am trying to serialize an EC private key to a PEM file, using the code:
The generated PEM file is like
I tried to use Python Cryptography to cross verify the generated PEM file and got an error saying 'Could not deserialize key data. The data may be in an incorrect format'.
By inspecting the prvObj, I found that the object have the following values:
{type: 'EC', isPrivate: true, isPublic: false,
and public key is null:pubKeyHex: null
Then I tried a different approach to generate the PEM file:
This time the generated PEM file is like:
And it can be crossed verified using Python Cryptography library. The prvKeyObj has the following values:
type: 'EC', isPrivate: true, isPublic: false
and both prvKeyHex and pubKeyHex are set.Out of curiosity, I set the public key hex to the private key object as in the first approach like:
This time it generates a correct PEM file that can be verified. However, the object has the values as follows:
type: 'EC', isPrivate: true, isPublic: true
and both prvKeyHex and pubKeyHex are set. Note that both isPrivate and isPublic are true this time.Further more, I used the incorrect PEM file in the CSR generation like:
It produced a valid CSR file just like using the correct private key PEM file which is weird but understandable.
If the last point is within the tolerance, the first PEM file definitely looks like a bug to me.