I generate a key on the HSM through the Graphene library, except when I try to get the public key raw value by getting its 'pointEC' attribute (equivalent to CKA_EC_POINT
), I get a 134 character string:
044104c9d5b656518b5b7e0d747b86328c37a0d507de9b3863a43e77b559ab60c0f9b15985f83a8c20588164c0634f98eb4a4cf8ce70020e94ae21a247904fac8b1010
Now, I understand for this standard there's an X and Y integer, but I read that some math is required to make them valid for generating an Ethereum address. I also understand that the '04' means that it is an uncompressed public key, but I do not know why the '4104' keeps popping up or what it means. Are these just different ways of representing the same data? Could I just take the last 128 characters and hash it for a valid Ethereum address?
What you are seeing is a BER/DER encoded uncompressed point. The first byte valued 04
is not the uncompressed point indicator. That's the 3rd byte. The first byte valued 04
encodes the tag byte for an ASN.1 OCTET STRING (also known as a byte array to most developers). You can view the structure here.
The byte with hex value 41
is the size of the bytes that comes after: 1 byte for the 04
uncompressed point indicator, 32 bytes for the statically sized X-coordinate and 32 bytes for the Y-coordinate.
So yes, you can take the last 64 bytes and split it in two if you need the X- and Y-coordinate. The 128 characters are just the hexadecimal representation of those bytes - but you should just worry about the bytes.
Of course, what you should do is to parse the ASN.1, determine and validate the length, take the uncompressed point, decode it and check that it is on the curve to validate your input. An EC key is valid if it includes the correct parameters. For Ethereum / BitCoin the curve is however implicitly known (secp256k1).