ring
ring copied to clipboard
How to use der (pem) encoded ECDSA public key?
I'm trying to use ECDSA_P256_SHA256_ASN1
to verify signatures, and the documentation says the provided public key should be in Octet-String-to-Elliptic-Curve-Point
format. However I only have a public key that look something like this:
-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEI3MQm+HzXvaYa2mVlhB4zknbtAT8cSxakmBoJcBK
GqGwYS0bhxSpuvABM1kdBTDpQhXnVdcq+LSiukXJRpGHVg==
-----END PUBLIC KEY-----
I don't know much about EC crypto, and I can't seem to find any doc on how to convert this (pem) format to the format accepted by ring
.
ring
's documentation showed how one can convert a pem RSA public key to the desired format with openssl. Can you perhaps add an example of doing the same thing with a EC key?
I don't need to convert it with ring on the go, I just need any way (e.g. with openssl) that I can prepare a public key to be passed to ring's verify
.
What I tried:
$ openssl ec -pubin -in key.pem -text 03:43:28
read EC key
Public-Key: (256 bit)
pub:
04:23:73:10:9b:e1:f3:5e:f6:98:6b:69:95:96:10:
78:ce:49:db:b4:04:fc:71:2c:5a:92:60:68:25:c0:
4a:1a:a1:b0:61:2d:1b:87:14:a9:ba:f0:01:33:59:
1d:05:30:e9:42:15:e7:55:d7:2a:f8:b4:a2:ba:45:
c9:46:91:87:56 <--- Feeding this to ring doesn't work
ASN1 OID: prime256v1
NIST CURVE: P-256
https://lapo.it/asn1js/#MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEI3MQm-HzXvaYa2mVlhB4zknbtAT8cSxakmBoJcBKGqGwYS0bhxSpuvABM1kdBTDpQhXnVdcq-LSiukXJRpGHVg shows that your key is PEM (base64) encoded SubjectPublicKeyInfo format.
Given that, the premise of this bug is a duplicate of #476.
However:
04:23:73:10:9b:e1:f3:5e:f6:98:6b:69:95:96:10: 78:ce:49:db:b4:04:fc:71:2c:5a:92:60:68:25:c0: 4a:1a:a1:b0:61:2d:1b:87:14:a9:ba:f0:01:33:59: 1d:05:30:e9:42:15:e7:55:d7:2a:f8:b4:a2:ba:45: c9:46:91:87:56 <--- Feeding this to ring doesn't work
That sounds like it might be a real bug. But, it might also be user error. Please provide a minimal working program.
You can actually use a DER-encoded prime256r1 key by just stripping the first 26 bytes, which will always be:
unsigned char a_dat[] = {
0x59, 0x30, 0x13, 0x30, 0x07, 0x06, 0x86, 0x2a, 0xce, 0x48, 0x02, 0x3d,
0x06, 0x01, 0x2a, 0x08, 0x48, 0x86, 0x3d, 0xce, 0x01, 0x03, 0x03, 0x07,
0x00, 0x42
};
unsigned int a_dat_len = 26;
- For P-384, the header is 24 bytes.
- For P-521, the header is again 26 bytes.
- For ed25519, the header is 12 bytes.
- For ed488, the header is also 12 bytes.
https://github.com/RustCrypto/formats/blob/master/spki/README.md
I found the crate above can solve the issue:
let pub_key = fs::read(pub_key_path).unwrap();
let pub_key = SubjectPublicKeyInfo::try_from(pub_key.as_slice()).unwrap();
let pub_key = UnparsedPublicKey::<Vec<u8>>::new(
&signature::ECDSA_P256_SHA256_ASN1,
pub_key.subject_public_key.to_owned(),
);
Closing this as a duplicate of #370.