ECPrivateKey does not zero-pad private key, violates rfc5915
See original GitHub issueHi,
https://tools.ietf.org/html/rfc5915:
privateKey is the private key. It is an octet string of length ceiling (log2(n)/8) (where n is the order of the curve) obtained from the unsigned integer via the Integer-to-Octet-String- Primitive (I2OSP) defined in [RFC3447].
I.e. the encoded number must be padded with zeros. Best rationale I can think of is that an encrypted ec key would leak information (key size) otherwise.
asn1crypto uses IntegerOctetString which cannot be told the encoded width of the number. I.e. the number is not padded.
IntegerOctetString is only used in ECPrivateKey.
Code that wants to generate a correct ECPrivateKey structure would need to pass the intended length of the key. I don’t see any way around this; asn1crypto cannot determine the width by any other means.
I’m not sure how the API should look like. (31337, 32)? Or {'value': 31337, 'width': 32}? Or add a new class method which takes value + width?
A breaking change (i.e. do not accept a plain int) might be acceptable; existing code is incorrect anyway.
.native should still return an int. Actual encoding (and its length) can be read with .contents.
Thanks!
Incorrect key (generated by asn1crypto):
-----BEGIN PRIVATE KEY-----
MGkCAQAwEwYHKoZIzj0CAQYIKoZIzj0DAQcETzBNAgEBBAJ6aaFEA0IABC+quZfc
dJWlahQfx2dJjqCwY65KkbxAVUU/7WfnnwVfOaIKLFq1YIfiQ/6pjmr+soVeoJIm
hetpZvE17EgMWEM=
-----END PRIVATE KEY-----
Correct key (generated by openssl):
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHppoAoGCCqGSM49
AwEHoUQDQgAEL6q5l9x0laVqFB/HZ0mOoLBjrkqRvEBVRT/tZ+efBV85ogosWrVg
h+JD/qmOav6yhV6gkiaF62lm8TXsSAxYQw==
-----END EC PRIVATE KEY-----
Code to generate above key:
from asn1crypto.keys import ECPointBitString, ECPrivateKey, NamedCurve, PrivateKeyInfo
from asn1crypto.pem import armor
key = PrivateKeyInfo.wrap(
ECPrivateKey({
'version': 1,
'private_key': 31337,
'parameters': NamedCurve('secp256r1'),
'public_key': ECPointBitString.from_coords(
0x2faab997dc7495a56a141fc767498ea0b063ae4a91bc4055453fed67e79f055f,
0x39a20a2c5ab56087e243fea98e6afeb2855ea0922685eb6966f135ec480c5843,
),
}),
'ec'
)
print(armor('PRIVATE KEY', key.dump()).decode(), end="")
Issue Analytics
- State:
- Created 5 years ago
- Comments:7 (6 by maintainers)

Top Related StackOverflow Question
This should be fixed by 61ae7d7790e460f253c29c5ab7c63b0149f44154
As a note to others, I have a fix for this mostly implemented, and will be pushed up once I have time to complete it.