@nfen/webcrypto-ts
Version:
Enforced Webcrypto wrapper
186 lines • 6.07 kB
JavaScript
/**
* Code related to RSA_OAEP
* @module
*/
import { getKeyUsagePairsByAlg } from "../key_usages.js";
import * as proxy from "../proxy.js";
import { Alg as SHA } from "../sha/shared.js";
import * as WebCrypto from "../webcrypto.js";
import { Alg, RsaShared, } from "./shared.js";
const handlers = {
privHandler: {
get(target, prop) {
switch (prop) {
case "self":
return target;
case "decrypt":
return (algorithm, data) => decrypt(algorithm, target, data);
case "unwrapKey":
return (format, wrappedKey, wrappedKeyAlgorithm, unwrappingKeyAlgorithm, extractable, keyUsages) => unwrapKey(format, wrappedKey, wrappedKeyAlgorithm, target, unwrappingKeyAlgorithm, extractable, keyUsages);
case "exportKey":
return (format) => exportKey(format, target);
}
return Reflect.get(target, prop);
},
},
pubHandler: {
get(target, prop) {
switch (prop) {
case "self":
return target;
case "encrypt":
return (algorithm, data) => encrypt(algorithm, target, data);
case "wrapKey":
return (format, key, wrapAlgorithm) => wrapKey(format, key, target, wrapAlgorithm);
case "exportKey":
return (format) => exportKey(format, target);
}
return Reflect.get(target, prop);
},
},
};
/**
* Generate a new RSA_OAEP keypair
* @example
* ```ts
* const keyPair = await RSA_OAEP.generateKey();
* ```
*/
export const generateKey = async (algorithm = {
hash: SHA.Variant.SHA_512,
modulusLength: 4096,
publicExponent: new Uint8Array([0x01, 0x00, 0x01]),
}, extractable, keyUsages) => {
const keyPair = (await RsaShared.generateKey({
...algorithm,
name: Alg.Variant.RSA_OAEP,
}, extractable, keyUsages));
return proxy.proxifyKeyPair(handlers)(keyPair);
};
/**
* Generate a new RSA_OAEP keypair
* @alias generateKey
* @example
* ```ts
* const keyPair = await RSA_OAEP.generateKeyPair();
* ```
*/
export const generateKeyPair = generateKey;
/**
* Import an RSA_OAEP public or private key
* @example
* ```ts
* const key = await RSA_OAEP.importKey("jwk", pubKey, { hash: "SHA-512" }, true, ['encrypt']);
* ```
*/
export const importKey = async (format, key, algorithm, extractable, keyUsages) => {
const importedKey = await RsaShared.importKey(format, key, { ...algorithm, name: Alg.Variant.RSA_OAEP }, extractable, keyUsages);
if (importedKey.type === "private") {
return proxy.proxifyKey(handlers.privHandler)(importedKey);
}
else {
return proxy.proxifyKey(handlers.pubHandler)(importedKey);
}
};
/**
* Export an RSA_OAEP public or private key
* @example
* ```ts
* const pubKeyJwk = await RSA_OAEP.exportKey("jwk", keyPair.publicKey.self);
* ```
* @example
* ```ts
* const pubKeyJwk = await keyPair.publicKey.exportKey("jwk");
* const privKeyJwk = await keyPair.privateKey.exportKey("jwk");
* ```
*/
export const exportKey = async (format, key) => RsaShared.exportKey(format, key);
/**
* Encrypt with an RSA_OAEP public key
* @example
* ```ts
* const message = new TextEncoder().encode("a message");
* const data = await RSA_OAEP.encrypt({label}, keyPair.publicKey.self, message);
* ```
* @example
* ```ts
* const message = new TextEncoder().encode("a message");
* const data = await keyPair.publicKey.encrypt({label}, message);
* ```
*/
export async function encrypt(algorithm = {}, key, data) {
return await WebCrypto.encrypt({
...algorithm,
name: Alg.Variant.RSA_OAEP,
}, key, data);
}
/**
* Decrypt with an RSA_OAEP private key
* @example
* ```ts
* const data = await RSA_OAEP.decrypt({label}, keyPair.privateKey.self, data);
* ```
* @example
* ```ts
* const data = await keyPair.privateKey.decrypt({label}, data);
* ```
*/
export async function decrypt(algorithm = {}, key, data) {
return await WebCrypto.decrypt({
...algorithm,
name: Alg.Variant.RSA_OAEP,
}, key, data);
}
/**
* Wrap another key with an RSA_OAEP public key
* @example
* ```ts
* const kek = await RSA_OAEP.generateKey(undefined, true, ['wrapKey', 'unwrapKey']);
* const dek = await RSA_OAEP.generateKey();
* const label = await Random.getValues(8);
* const wrappedKey = await RSA_OAEP.wrapKey("raw", dek.self, kek.self, {label});
* ```
* @example
* ```ts
* const kek = await RSA_OAEP.generateKey(undefined, true, ['wrapKey', 'unwrapKey']);
* const dek = await RSA_OAEP.generateKey();
* const label = await Random.getValues(8);
* const wrappedKey = await kek.wrapKey("raw", dek.self, {label});
* ```
*/
export async function wrapKey(format, key, wrappingkey, wrapAlgorithm) {
const _wrapAlgorithm = {
...wrapAlgorithm,
name: Alg.Variant.RSA_OAEP,
};
return await WebCrypto.wrapKey(format, key, wrappingkey, _wrapAlgorithm);
}
/**
* Unwrap a wrapped key using the key encryption key
* @example
* ```ts
* const wrappedKey = await RSA_OAEP.wrapKey("raw", dek.self, kek.self);
* const unwrappedKey = await RSA_OAEP.unwrapKey(
* "raw",
* wrappedKey,
* { name: Alg.Mode.RSA_OAEP },
* kek.self,
* );
* ```
* ```ts
* const wrappedKey = await kek.wrapKey("raw", dek.self);
* const unwrappedKey = await kek.unwrapKey(
* "raw",
* wrappedKey,
* { name: Alg.Mode.RSA_OAEP },
* );
* ```
*/
export async function unwrapKey(format, wrappedKey, wrappedKeyAlgorithm, unwrappingKey, unwrappingKeyAlgorithm, extractable = true, keyUsages) {
const _unwrappingKeyAlgorithm = {
...unwrappingKeyAlgorithm,
name: Alg.Variant.RSA_OAEP,
};
return await WebCrypto.unwrapKey(format, wrappedKey, unwrappingKey, _unwrappingKeyAlgorithm, wrappedKeyAlgorithm, extractable, keyUsages ?? getKeyUsagePairsByAlg(wrappedKeyAlgorithm.name));
}
//# sourceMappingURL=rsa_oaep.js.map