Skip to content

Instantly share code, notes, and snippets.

@OR13
Created September 30, 2022 19:35
Show Gist options
  • Save OR13/7d99f46c56e7f78082097452158125ef to your computer and use it in GitHub Desktop.
Save OR13/7d99f46c56e7f78082097452158125ef to your computer and use it in GitHub Desktop.
opacity: 1;
import crypto from 'crypto'
import assert from 'assert';
import { Kem, Kdf, Aead, CipherSuite } from 'hpke-js'
const suite = new CipherSuite({
kem: Kem.DhkemP256HkdfSha256,
kdf: Kdf.HkdfSha256,
aead: Aead.Aes128Gcm
});
const encryptMessage = async (publicKeyJwk, message)=> {
const importedPublicKey = await crypto.subtle.importKey('jwk', {...publicKeyJwk, key_ops: ['deriveBits']}, {
name: "ECDH",
namedCurve: "P-256"
}, true, ['deriveBits'])
const sender = await suite.createSenderContext({
recipientPublicKey: importedPublicKey
});
const ct = await sender.seal(message);
const encodedSender = Buffer.from(sender.enc).toString('hex')
let epk = {
kty: publicKeyJwk.kty,
crv: publicKeyJwk.crv,
key_ops: ['deriveBits'],
x: Buffer.from(encodedSender.slice(2, 66), 'hex').toString('base64'),
y: Buffer.from(encodedSender.slice(66), 'hex').toString('base64')
}
const encRaw = Uint8Array.from(Buffer.from(encodedSender, 'hex'));
const encJwk = JSON.stringify(epk)
const encCwk = undefined;
const encMultibase = undefined;
const encPem = undefined;
const encHex = undefined;
const encBase64 = undefined;
const encBase58 = undefined;
return { ct, encRaw, encJwk, encCwk, encMultibase, encPem, encHex, encBase64, encBase58 }
}
// sniff encAny, and transform to format expected by the underlying HPKE library
// In the case of dajiaji/hpke-js -> 04 + hex(x) + hex(y)
// In the case of ... -> ...
const decryptMessage = async (privateKeyJwk, encAny, ct) =>{
const importedPrivateKey = await crypto.subtle.importKey('jwk', {...privateKeyJwk, key_ops: ['deriveBits']}, {
name: "ECDH",
namedCurve: "P-256"
}, true, ['deriveBits'])
let decodedSender = undefined;
if (typeof encAny === 'string'){
const publicKeyJwk = JSON.parse(encAny)
const buffer = Buffer.concat([Buffer.from('04', 'hex'), Buffer.from(publicKeyJwk.x, 'base64'), Buffer.from(publicKeyJwk.y, 'base64')])
decodedSender = Uint8Array.from(buffer)
} else {
decodedSender = encAny
}
const recipient = await suite.createRecipientContext({
recipientKey: importedPrivateKey,
enc: decodedSender,
});
const pt = await recipient.open(ct);
return pt
}
(async ()=>{
const rkp = await suite.generateKeyPair();
const publicKeyJwk = await crypto.subtle.exportKey('jwk', rkp.publicKey )
const privateKeyJwk = await crypto.subtle.exportKey('jwk', rkp.privateKey )
const message = new TextEncoder().encode("hello world!");
const { ct, encRaw, encJwk } = await encryptMessage(publicKeyJwk, message)
const pt1 = await decryptMessage(privateKeyJwk, encRaw, ct)
assert(new TextDecoder().decode(pt1) === 'hello world!', 'Failed to decrypt message.')
const pt2 = await decryptMessage(privateKeyJwk, encJwk, ct)
assert(new TextDecoder().decode(pt2) === 'hello world!', 'Failed to decrypt message.')
})()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment