You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
68 lines
2.4 KiB
68 lines
2.4 KiB
1 year ago
|
|
||
|
# NOTES on working with Cryptographic Keys
|
||
|
|
||
|
Since the VAPID key pair was created using cyprto.createECDH we could reconstitute our public key
|
||
|
using only the private key:
|
||
|
```
|
||
|
const curveName = 'prime256v1';
|
||
|
const ecdh = crypto.createECDH(curveName);
|
||
|
const privateKeyBuffer = Buffer.from(privateKey, 'base64');
|
||
|
ecdh.setPrivateKey(privateKeyBuffer);
|
||
|
const rawPublicKeyBuffer = ecdh.getPublicKey();
|
||
|
|
||
|
```
|
||
|
|
||
|
Unfortunately, crypto module creates only "raw" keys. And when working with jsonwebtoken.sign method
|
||
|
we must have a PEM or something with ASN metadata. So, we create PEMs using eckeys-util module:
|
||
|
|
||
|
```
|
||
|
const pems = ecKeyUtils.generatePem({curveName, privateKey: ecdh.getPrivateKey(), publicKey: rawPublicKeyBuffer });
|
||
|
|
||
|
console.log("privateKey: ", pems.privateKey);
|
||
|
console.log();
|
||
|
console.log("publicKey: ", pems.publicKey);
|
||
|
|
||
|
const jwtToken = jwt.sign(jwtInfo, pems.privateKey, { algorithm: 'ES256' });
|
||
|
```
|
||
|
|
||
|
|
||
|
I trie here to create my own ASN1 metadata but this seems doomed due to ignorance of what were the required
|
||
|
components:
|
||
|
```
|
||
|
const asn1Header = Buffer.from('3059301306072a8648ce3d020106082a8648ce3d030107034200', 'hex');
|
||
|
const derPublicKeyBuffer = Buffer.concat([asn1Header, rawPublicKeyBuffer]);
|
||
|
const base64DerPublicKey = derPublicKeyBuffer.toString('base64');
|
||
|
console.log("base64DerPublicKey: ", base64DerPublicKey)
|
||
|
```
|
||
|
Such an approach creates a DER key pair. An alternative to that method is:
|
||
|
```
|
||
|
const ders = ecKeyUtils.generateDer({curveName, privateKey: ecdh.getPrivateKey(), publicKey: rawPublicKeyBuffer });
|
||
|
console.log("privateKey: ", ders.privateKey);
|
||
|
console.log("publicKey: ", ders.publicKey);
|
||
|
```
|
||
|
|
||
|
... using eckeys-util again ... but I'm not 100% sure if these have all the necessary ASN1 metadata AND
|
||
|
the DER key will produce this error ...
|
||
|
|
||
|
```
|
||
|
Error: secretOrPrivateKey must be an asymmetric key when using ES256
|
||
|
at module.exports [as sign] (/usr/src/app/node_modules/jsonwebtoken/sign.js:124:22)
|
||
|
|
||
|
```
|
||
|
... when used in the sign method. So, apparently, sign does not like the DER binary format but it is
|
||
|
fine with PEM.
|
||
|
|
||
|
## When sending a notification request to the Mozilla endpoint it does not like the Crypto-Key header:
|
||
|
|
||
|
```
|
||
|
{
|
||
|
"code":400,
|
||
|
"errno":110,
|
||
|
"error":"Bad Request",
|
||
|
"message":"Invalid aes128gcm Crypto-Key header",
|
||
|
"more_info":"http://autopush.readthedocs.io/en/latest/http.html#error-codes"
|
||
|
}
|
||
|
|
||
|
```
|
||
|
|