# 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" } ``` fcm.google.com push server: ``` authorization header had invalid format. authorization header should have the following format: t=jwtToken; k=base64(publicApplicationServerKey) 403 ```