simplito / elliptic-php

Fast, general Elliptic Curve Cryptography library. Supports curves used in Bitcoin, Ethereum and other cryptocurrencies (secp256k1, ed25519, ..)
MIT License
211 stars 53 forks source link

Generate signature from PKCS#8 file (itunes) #13

Closed mpoiriert closed 5 years ago

mpoiriert commented 5 years ago

Hi !

I am trying to do this using your library:

https://developer.apple.com/documentation/storekit/in-app_purchase/generating_a_signature_for_subscription_offers

Can you provide any help ?

ldudzsim commented 5 years ago

We do not provide PKCS#8 parsing, so you have to parse your private key using some other lib. After parsing you should get information about your private key (curve, privkey bn) which you can use to create private key using our lib. After that you can follow ECDSA example to get DER-formated signature.

Stafox commented 5 years ago

@ldudzsim could you tell please what kind of these info is needed to create private key? image

ldudzsim commented 5 years ago

Sorry for delay. First of all you pasted public key definition, so you missing the most important part of key (S2K) which is the private key "number", so there is no way to create private key from public. But in encoded private key there is also public key encoded and it looks the same as at your image, and it contains important stuff. The most important is curve identifier (you can get it from curve_name or curve_oid), you should use it to initialize EC

$ec = new EC($curveName);

unfortunetly you use prime256v1 curve, which is not supported by our lib (we only supports secp256k1, p192, p224, p256, p384, p521, curve25519, ed25519). But if you want to load another key with supported curve, you can go to next step. As you can see, you have x and y which define a point. This point directly defines a public key. For EC you can import you public key by encoding x and y to hex and using this code:

$ec = new EC($curveName);

// Public key as '04 + x + y'
$pub = "04" + bin2hex($x) + bin2hex($y);

// Import public key
$key = $ec->keyFromPublic($pub, 'hex');

if you are loading private key it is important to import also public key to verify key integrity (checking that public key match to private). If you are loading real private you should also have kdf (which is optional) and S2K. S2K is just private key big number so you can use it almost directly. It only contains 2 bytes with key length at beginning and checksum at the end. If you extract private key buffer you can import it using this code:

$ec = new EC($curveName);
$priv = $ec->keyFromPrivate($priv_hex);
Stafox commented 5 years ago

@ldudzsim thanks for info. I meant not generating the private key (because provided screenshot it is a details of P8 private key), but the private hex.

By the way, I found a workaround with openssl lib.

mpoiriert commented 5 years ago

I have been able to do this simply by using open_ssl, so no need of this or other third party library.

My answer on stackoverflow: https://stackoverflow.com/questions/55414749/generating-a-signature-for-subscription-offers-xcode-swift/55733695#55733695