@ldclabs/cose-ts
Version:
Implemented Keys, Algorithms (RFC9053), COSE (RFC9052) and CWT (RFC8392) in TypeScript.
71 lines • 2.23 kB
JavaScript
// (c) 2023-present, LDC Labs. All rights reserved.
// See the file LICENSE for licensing terms.
import { gcm } from '@noble/ciphers/webcrypto';
import * as iana from './iana';
import { assertBytes } from './map';
import { Key } from './key';
import { randomBytes, decodeCBOR } from './utils';
// TODO: more checks
// AesGcmKey implements content encryption algorithm AES-GCM for COSE as defined in RFC9053.
// https://datatracker.ietf.org/doc/html/rfc9053#name-aes-gcm.
export class AesGcmKey extends Key {
static fromBytes(data) {
return new AesGcmKey(decodeCBOR(data));
}
static generate(alg, kid) {
return AesGcmKey.fromSecret(randomBytes(getKeySize(alg)), kid);
}
static fromSecret(secret, kid) {
const alg = getAlg(assertBytes(secret, 'secret'));
const key = new AesGcmKey();
key.alg = alg;
if (kid != null) {
key.setKid(kid);
}
key.setParam(iana.SymmetricKeyParameterK, secret);
return key;
}
constructor(kv) {
super(kv);
this.kty = iana.KeyTypeSymmetric;
}
nonceSize() {
return 12;
}
getSecretKey() {
return this.getBytes(iana.SymmetricKeyParameterK, 'k');
}
async encrypt(plaintext, nonce, aad) {
const cipher = gcm(this.getSecretKey(), nonce, aad);
return cipher.encrypt(plaintext);
}
async decrypt(ciphertext, nonce, aad) {
const cipher = gcm(this.getSecretKey(), nonce, aad);
return cipher.decrypt(ciphertext);
}
}
function getKeySize(alg) {
switch (alg) {
case iana.AlgorithmA128GCM:
return 16;
case iana.AlgorithmA192GCM:
return 24;
case iana.AlgorithmA256GCM:
return 32;
default:
throw new Error(`cose-ts: unsupported AES-GCM alg ${alg}`);
}
}
function getAlg(key) {
switch (key.length) {
case 16:
return iana.AlgorithmA128GCM;
case 24:
return iana.AlgorithmA192GCM;
case 32:
return iana.AlgorithmA256GCM;
default:
throw new Error(`cose-ts: unsupported AES-GCM key length ${key.length}`);
}
}
//# sourceMappingURL=aesgcm.js.map