PeculiarVentures / graphene

A simple layer for interacting with PKCS #11 / PKCS11 / CryptoKI for Node in TypeScript. (Keywords: Javascript, PKCS#11, Crypto, Smart Card, HSM)
MIT License
169 stars 34 forks source link

How to extract public key from ECDSA (secp256k1) #127

Closed wshbair closed 4 years ago

wshbair commented 4 years ago

An stackoverflow said to extract the public key we need to " pull out the public key using its "pointEC" attribute: " is it true ?

rmhrisk commented 4 years ago

Not sure I understand.

it is possible to derive the public key of a given private key with secp256k1 - https://bitcoin.stackexchange.com/questions/25024/how-do-you-get-a-bitcoin-public-key-from-a-private-key

But your implementation may also just set CKO_PUBLIC_KEY containing the corresponding public key.

microshine commented 4 years ago

@wshbair If you need to export EC public key from PKCS#11 object use pointEC

node-webcrypto-p11 is based on graphene-pk11 implements WebCrypto interface and allows to export EC keys in PKCS8, SPKI and JWK formats.

https://github.com/PeculiarVentures/node-webcrypto-p11/blob/master/src/mechs/ec/crypto.ts#L192

wshbair commented 4 years ago

@microshine @rmhrisk Thanks for answering my question, Yes, it seems true to use the pointEC, however it includes uncompressed public key. Based on some expirments with SoftHSMv2 the pointEC length is 67 Bytes, so to get valid key I need to remove the first 3 bytes (keys.publicKey.getAttribute({pointEC: null}).pointEC.slice(3,67)).

This approach has been tested to generate Ethereum address and recovre the public key from a signed message.

microshine commented 4 years ago

Source code from node-webcrypto-p11 for uncompressed EC point decoding https://github.com/PeculiarVentures/node-webcrypto-p11/blob/master/src/mechs/ec/utils.ts#L36-L49

wshbair commented 4 years ago

I integrated the EC point decoding function . It assumes the public key is 65 Byte, which it MUST be accoring to RFC5480. The first byte is "04" of uncompressed key. So by the given function we remove the first Byte.

In my case, the retrun key is 67 bytes where it always start with "044104", so I need to remove the first 3 bytes to make it works. it may be a bug ?

microshine commented 4 years ago

It's ASN encoded value 04 - OCTET STRING 41 - Length 65 bytes

image

For secp256k1 curve it's always 044104 at the beginning

wshbair commented 4 years ago

@microshine that makes sense, thanks for support!