@peculiar/webcrypto-test
Version:
Vitest and Mocha tests of WebCrypto API
1,358 lines (1,343 loc) • 115 kB
JavaScript
/**
* Copyright (c) 2020-2026, Peculiar Ventures
* SPDX-License-Identifier: MIT
*/
'use strict';
var assert = require('assert');
var pvtsutils = require('pvtsutils');
function _interopNamespaceDefault(e) {
var n = Object.create(null);
if (e) {
Object.keys(e).forEach(function (k) {
if (k !== 'default') {
var d = Object.getOwnPropertyDescriptor(e, k);
Object.defineProperty(n, k, d.get ? d : {
enumerable: true,
get: function () { return e[k]; }
});
}
});
}
n.default = e;
return Object.freeze(n);
}
var assert__namespace = /*#__PURE__*/_interopNamespaceDefault(assert);
function getGlobalTestPlatform() {
const globalTests = globalThis;
return {
describe: globalTests.describe,
it: globalTests.it,
};
}
function createTestPlatform(platform) {
const resolved = platform ?? getGlobalTestPlatform();
if (!resolved.describe || !resolved.it) {
throw new Error("WebcryptoTest requires a test platform. Pass { describe, it } or enable globals in your test runner.");
}
return {
describe: resolved.describe,
it: resolved.it,
};
}
async function importKey(crypto, key) {
if (key.format === "jwk") {
return crypto.subtle.importKey(key.format, key.data, key.algorithm, key.extractable, key.keyUsages);
}
return crypto.subtle.importKey(key.format, key.data, key.algorithm, key.extractable, key.keyUsages);
}
async function getKeys(crypto, key) {
const keys = {};
if ("privateKey" in key) {
keys.privateKey = await importKey(crypto, key.privateKey);
keys.publicKey = await importKey(crypto, key.publicKey);
}
else {
keys.privateKey = keys.publicKey = await importKey(crypto, key);
}
return keys;
}
async function wrapTest(promise, action, index, platform) {
const test = action.skip
? platform.it.skip ?? platform.it
: action.only
? platform.it.only ?? platform.it
: platform.it;
test(action.name || `#${index + 1}`, async () => {
if (action.error) {
await assert.rejects(promise(), action.error);
}
else {
await promise();
}
});
}
function isKeyPair(obj) {
return obj.privateKey && obj.publicKey;
}
function testGenerateKey(generateKey, crypto, platform) {
platform.describe("Generate Key", () => {
generateKey.forEach((action, index) => {
wrapTest(async () => {
const algorithm = Object.assign({}, action.algorithm);
algorithm.name = algorithm.name.toLowerCase();
const key = await crypto.subtle.generateKey(algorithm, action.extractable, action.keyUsages);
assert(key);
if (!isKeyPair(key)) {
const generatedKey = key;
assert.equal(generatedKey.algorithm.name, action.algorithm.name, "Algorithm name MUST be equal to incoming algorithm and in the same case");
assert.equal(generatedKey.extractable, action.extractable);
assert.deepEqual(generatedKey.usages, action.keyUsages);
}
else {
const generatedKey = key;
assert(generatedKey.privateKey);
assert.equal(generatedKey.privateKey.algorithm.name, action.algorithm.name, "Algorithm name MUST be equal to incoming algorithm and in the same case");
assert.equal(generatedKey.privateKey.extractable, action.extractable);
assert(generatedKey.publicKey);
assert.equal(generatedKey.publicKey.algorithm.name, action.algorithm.name, "Algorithm name MUST be equal to incoming algorithm and in the same case");
assert.equal(generatedKey.publicKey.extractable, true);
}
action.assert?.(key);
}, action, index, platform);
});
});
}
function testImport(importFn, crypto, platform) {
platform.describe("Import/Export", () => {
importFn.forEach((action, index) => {
wrapTest(async () => {
const importedKey = await crypto.subtle.importKey(action.format, action.data, action.algorithm, action.extractable, action.keyUsages);
if (!action.extractable) {
return;
}
const exportedData = await crypto.subtle.exportKey(action.format, importedKey);
if (action.format === "jwk") {
assert.deepEqual(exportedData, action.data);
}
else {
assert.equal(Buffer.from(exportedData).toString("hex"), Buffer.from(action.data).toString("hex"));
}
action.assert?.(importedKey);
}, action, index, platform);
});
});
}
function testSign(sign, crypto, platform) {
platform.describe("Sign/Verify", () => {
sign.forEach((action, index) => {
wrapTest(async () => {
const keys = await getKeys(crypto, action.key);
const verifyKey = keys.publicKey;
const signKey = keys.privateKey;
const algorithm = Object.assign({}, action.algorithm);
algorithm.name = algorithm.name.toLowerCase();
const signature = await crypto.subtle.sign(algorithm, signKey, action.data);
let ok = await crypto.subtle.verify(algorithm, verifyKey, signature, action.data);
assert.equal(true, ok, "Cannot verify signature from Action data");
ok = await crypto.subtle.verify(algorithm, verifyKey, action.signature, action.data);
if (!ok) {
assert.equal(pvtsutils.Convert.ToHex(signature), pvtsutils.Convert.ToHex(action.signature));
}
assert.equal(true, ok);
}, action, index, platform);
});
});
}
function testDeriveBits(deriveBits, crypto, platform) {
platform.describe("Derive bits", () => {
deriveBits.forEach((action, index) => {
wrapTest(async () => {
const keys = await getKeys(crypto, action.key);
const algorithm = Object.assign({}, action.algorithm, { public: keys.publicKey });
algorithm.name = algorithm.name.toLowerCase();
const derivedBits = await crypto.subtle.deriveBits(algorithm, keys.privateKey, action.length);
assert.equal(pvtsutils.Convert.ToHex(derivedBits), pvtsutils.Convert.ToHex(action.data));
}, action, index, platform);
});
});
}
function testDeriveKey(deriveKey, crypto, platform) {
platform.describe("Derive key", () => {
deriveKey.forEach((action, index) => {
wrapTest(async () => {
const keys = await getKeys(crypto, action.key);
const algorithm = Object.assign({}, action.algorithm, { public: keys.publicKey });
algorithm.name = algorithm.name.toLowerCase();
const derivedKey = await crypto.subtle.deriveKey(algorithm, keys.privateKey, action.derivedKeyType, true, action.keyUsages);
const keyData = await crypto.subtle.exportKey(action.format, derivedKey);
if (action.format === "jwk") {
assert.deepEqual(keyData, action.keyData);
}
else {
assert.equal(pvtsutils.Convert.ToHex(keyData), pvtsutils.Convert.ToHex(action.keyData));
}
action.assert?.(derivedKey);
}, action, index, platform);
});
});
}
function testWrap(wrapKey, crypto, platform) {
platform.describe("Wrap/Unwrap key", () => {
wrapKey.forEach((action, index) => {
wrapTest(async () => {
const wKey = (await getKeys(crypto, action.wKey)).privateKey;
const key = await getKeys(crypto, action.key);
const wrappedKey = await crypto.subtle.wrapKey(action.wKey.format, wKey, key.publicKey, action.algorithm);
if (action.wrappedKey) {
assert.equal(pvtsutils.Convert.ToHex(wrappedKey), pvtsutils.Convert.ToHex(action.wrappedKey));
}
const unwrappedKey = await crypto.subtle.unwrapKey(action.wKey.format, wrappedKey, key.privateKey, action.algorithm, action.wKey.algorithm, action.wKey.extractable, action.wKey.keyUsages);
assert.deepEqual(unwrappedKey.algorithm, wKey.algorithm);
}, action, index, platform);
});
});
}
function testDigest(digest, crypto, platform) {
platform.describe("Digest", () => {
digest.forEach((action, index) => {
wrapTest(async () => {
const hash = await crypto.subtle.digest(action.algorithm, action.data);
assert.equal(pvtsutils.Convert.ToHex(hash), pvtsutils.Convert.ToHex(action.hash));
}, action, index, platform);
});
});
}
function testEncrypt(encrypt, crypto, platform) {
platform.describe("Encrypt/Decrypt", () => {
encrypt.forEach((action, index) => {
wrapTest(async () => {
const keys = await getKeys(crypto, action.key);
const encKey = keys.publicKey;
const decKey = keys.privateKey;
const algorithm = Object.assign({}, action.algorithm);
algorithm.name = algorithm.name.toLowerCase();
const enc = await crypto.subtle.encrypt(algorithm, encKey, action.data);
let dec = await crypto.subtle.decrypt(algorithm, decKey, enc);
assert.equal(pvtsutils.Convert.ToHex(dec), pvtsutils.Convert.ToHex(action.data));
dec = await crypto.subtle.decrypt(algorithm, decKey, action.encData);
assert.equal(pvtsutils.Convert.ToHex(dec), pvtsutils.Convert.ToHex(action.data));
}, action, index, platform);
});
});
}
function testCrypto(crypto, param, platform) {
const testPlatform = createTestPlatform(platform);
testPlatform.describe(param.name, () => {
if (param.actions.generateKey) {
testGenerateKey(param.actions.generateKey, crypto, testPlatform);
}
if (param.actions.encrypt) {
testEncrypt(param.actions.encrypt, crypto, testPlatform);
}
if (param.actions.import) {
testImport(param.actions.import, crypto, testPlatform);
}
if (param.actions.sign) {
testSign(param.actions.sign, crypto, testPlatform);
}
if (param.actions.deriveBits) {
testDeriveBits(param.actions.deriveBits, crypto, testPlatform);
}
if (param.actions.deriveKey) {
testDeriveKey(param.actions.deriveKey, crypto, testPlatform);
}
const digest = param.actions.digest;
if (digest) {
testDigest(digest, crypto, testPlatform);
}
const wrapKey = param.actions.wrapKey;
if (wrapKey) {
testWrap(wrapKey, crypto, testPlatform);
}
});
}
const AES128CBC = {
name: "AES-128-CBC",
actions: {
generateKey: [
{
algorithm: { name: "AES-CBC", length: 128 },
extractable: true,
keyUsages: ["encrypt", "decrypt"],
},
],
encrypt: [
{
algorithm: {
name: "AES-CBC",
iv: Buffer.from("1234567890abcdef"),
},
data: Buffer.from("test message"),
encData: Buffer.from("d5df3ea1598defe7446420802baef28e", "hex"),
key: {
format: "raw",
data: Buffer.from("1234567890abcdef"),
algorithm: { name: "AES-CBC" },
extractable: true,
keyUsages: ["encrypt", "decrypt"],
},
},
],
import: [
{
name: "raw",
format: "raw",
data: Buffer.from("1234567890abcdef"),
algorithm: "AES-CBC",
extractable: true,
keyUsages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"],
},
{
name: "wrong key size",
error: Error,
format: "raw",
data: Buffer.from("12345678"),
algorithm: "AES-CBC",
extractable: true,
keyUsages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"],
},
{
name: "jwk",
format: "jwk",
data: {
kty: "oct",
alg: "A128CBC",
k: "MTIzNDU2Nzg5MGFiY2RlZg",
ext: true,
key_ops: ["encrypt", "decrypt", "wrapKey", "unwrapKey"],
},
algorithm: "AES-CBC",
extractable: true,
keyUsages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"],
},
],
wrapKey: [
{
key: {
format: "raw",
algorithm: "AES-CBC",
data: pvtsutils.Convert.FromBase64("AQIDBAUGBwgJAAECAwQFBg=="),
extractable: true,
keyUsages: ["wrapKey", "unwrapKey"],
},
wKey: {
format: "raw",
data: Buffer.from("1234567890abcdef"),
algorithm: "AES-CBC",
extractable: true,
keyUsages: ["encrypt", "decrypt"],
},
algorithm: {
name: "AES-CBC",
iv: Buffer.from("1234567890abcdef"),
},
wrappedKey: pvtsutils.Convert.FromHex("c630c4bf95977db13f386cc950b18e98521d54c4fda0ba15b2884d2695638bd9"),
},
],
}
};
const AES192CBC = {
name: "AES-192-CBC",
actions: {
generateKey: [
{
algorithm: { name: "AES-CBC", length: 192 },
extractable: true,
keyUsages: ["encrypt", "decrypt"],
},
],
encrypt: [
{
algorithm: {
name: "AES-CBC",
iv: Buffer.from("1234567890abcdef"),
},
data: Buffer.from("test message"),
encData: Buffer.from("67d0b3022149829bf009ad4aff19963a", "hex"),
key: {
format: "raw",
data: Buffer.from("1234567890abcdef12345678"),
algorithm: { name: "AES-CBC" },
extractable: true,
keyUsages: ["encrypt", "decrypt"],
},
},
],
import: [
{
name: "raw",
format: "raw",
data: Buffer.from("1234567890abcdef12345678"),
algorithm: "AES-CBC",
extractable: true,
keyUsages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"],
},
{
name: "jwk",
format: "jwk",
data: {
kty: "oct",
alg: "A192CBC",
k: "MTIzNDU2Nzg5MGFiY2RlZjEyMzQ1Njc4",
ext: true,
key_ops: ["encrypt", "decrypt", "wrapKey", "unwrapKey"],
},
algorithm: "AES-CBC",
extractable: true,
keyUsages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"],
},
],
}
};
const AES256CBC = {
name: "AES-256-CBC",
actions: {
generateKey: [
{
algorithm: { name: "AES-CBC", length: 256 },
extractable: true,
keyUsages: ["encrypt", "decrypt"],
},
],
encrypt: [
{
algorithm: {
name: "AES-CBC",
iv: Buffer.from("1234567890abcdef"),
},
data: Buffer.from("test message"),
encData: Buffer.from("d827c1c6aee9f0f552c62f30ddee83af", "hex"),
key: {
format: "raw",
data: Buffer.from("1234567890abcdef1234567809abcdef"),
algorithm: { name: "AES-CBC" },
extractable: true,
keyUsages: ["encrypt", "decrypt"],
},
},
],
import: [
{
name: "raw",
format: "raw",
data: Buffer.from("1234567890abcdef1234567890abcdef"),
algorithm: "AES-CBC",
extractable: true,
keyUsages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"],
},
{
name: "jwk",
format: "jwk",
data: {
kty: "oct",
alg: "A256CBC",
k: "MTIzNDU2Nzg5MGFiY2RlZjEyMzQ1Njc4OTBhYmNkZWY",
ext: true,
key_ops: ["encrypt", "decrypt", "wrapKey", "unwrapKey"],
},
algorithm: "AES-CBC",
extractable: true,
keyUsages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"],
},
],
}
};
const AES128CTR = {
name: "AES-128-CTR",
actions: {
generateKey: [
{
algorithm: { name: "AES-CTR", length: 128 },
extractable: true,
keyUsages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"],
},
],
encrypt: [
{
algorithm: {
name: "AES-CTR",
counter: Buffer.from("1234567890abcdef"),
length: 128,
},
data: Buffer.from("test message"),
encData: Buffer.from("e1d561c49ce4eb2f448f8a00", "hex"),
key: {
format: "raw",
data: Buffer.from("1234567890abcdef"),
algorithm: { name: "AES-CTR" },
extractable: true,
keyUsages: ["encrypt", "decrypt"],
},
},
],
import: [
{
name: "raw",
format: "raw",
data: Buffer.from("1234567890abcdef"),
algorithm: "AES-CTR",
extractable: true,
keyUsages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"],
},
{
name: "jwk",
format: "jwk",
data: {
kty: "oct",
alg: "A128CTR",
k: "MTIzNDU2Nzg5MGFiY2RlZg",
ext: true,
key_ops: ["encrypt", "decrypt", "wrapKey", "unwrapKey"],
},
algorithm: "AES-CTR",
extractable: true,
keyUsages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"],
},
],
}
};
const AES192CTR = {
name: "AES-192-CTR",
actions: {
generateKey: [
{
algorithm: { name: "AES-CTR", length: 192 },
extractable: true,
keyUsages: ["encrypt", "decrypt"],
},
],
encrypt: [
{
algorithm: {
name: "AES-CTR",
counter: Buffer.from("1234567890abcdef"),
length: 128,
},
data: Buffer.from("test message"),
encData: Buffer.from("55a00e2851f00aba53bbd02c", "hex"),
key: {
format: "raw",
data: Buffer.from("1234567890abcdef12345678"),
algorithm: { name: "AES-CTR" },
extractable: true,
keyUsages: ["encrypt", "decrypt"],
},
},
],
import: [
{
name: "raw",
format: "raw",
data: Buffer.from("1234567890abcdef12345678"),
algorithm: "AES-CTR",
extractable: true,
keyUsages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"],
},
{
name: "jwk",
format: "jwk",
data: {
kty: "oct",
alg: "A192CTR",
k: "MTIzNDU2Nzg5MGFiY2RlZjEyMzQ1Njc4",
ext: true,
key_ops: ["encrypt", "decrypt", "wrapKey", "unwrapKey"],
},
algorithm: "AES-CTR",
extractable: true,
keyUsages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"],
},
],
}
};
const AES256CTR = {
name: "AES-256-CTR",
actions: {
generateKey: [
{
algorithm: { name: "AES-CTR", length: 256 },
extractable: true,
keyUsages: ["encrypt", "decrypt"],
},
],
encrypt: [
{
algorithm: {
name: "AES-CTR",
counter: Buffer.from("1234567890abcdef"),
length: 128,
},
data: Buffer.from("test message"),
encData: Buffer.from("8208d011a20162c8af7a9ce5", "hex"),
key: {
format: "raw",
data: Buffer.from("1234567890abcdef1234567809abcdef"),
algorithm: { name: "AES-CTR" },
extractable: true,
keyUsages: ["encrypt", "decrypt"],
},
},
],
import: [
{
name: "raw",
format: "raw",
data: Buffer.from("1234567890abcdef1234567890abcdef"),
algorithm: "AES-CTR",
extractable: true,
keyUsages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"],
},
{
name: "jwk",
format: "jwk",
data: {
kty: "oct",
alg: "A256CTR",
k: "MTIzNDU2Nzg5MGFiY2RlZjEyMzQ1Njc4OTBhYmNkZWY",
ext: true,
key_ops: ["encrypt", "decrypt", "wrapKey", "unwrapKey"],
},
algorithm: "AES-CTR",
extractable: true,
keyUsages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"],
},
],
}
};
const AES128CMAC = {
name: "AES-128-CMAC",
only: true,
actions: {
generateKey: [
{
algorithm: { name: "AES-CMAC", length: 128 },
extractable: true,
keyUsages: ["sign", "verify"],
},
],
sign: [
{
algorithm: {
name: "AES-CMAC",
length: 256,
},
data: Buffer.from("test message"),
signature: Buffer.from("98038e3ad7500d11005b6789c6cf9672", "hex"),
key: {
format: "raw",
data: Buffer.from("1234567890abcdef"),
algorithm: { name: "AES-CMAC" },
extractable: true,
keyUsages: ["sign", "verify"],
},
},
],
import: [
{
name: "raw",
format: "raw",
data: Buffer.from("1234567890abcdef"),
algorithm: "AES-CMAC",
extractable: true,
keyUsages: ["sign", "verify"],
},
{
name: "jwk",
format: "jwk",
data: {
kty: "oct",
alg: "A128CMAC",
k: "MTIzNDU2Nzg5MGFiY2RlZg",
ext: true,
key_ops: ["sign", "verify"],
},
algorithm: "AES-CMAC",
extractable: true,
keyUsages: ["sign", "verify"],
},
],
}
};
const AES192CMAC = {
name: "AES-192-CMAC",
only: true,
actions: {
generateKey: [
{
algorithm: { name: "AES-CMAC", length: 192 },
extractable: true,
keyUsages: ["sign", "verify"],
},
],
sign: [
{
algorithm: {
name: "AES-CMAC",
length: 192,
},
data: Buffer.from("test message"),
signature: Buffer.from("fe5c107cbcafd8a0a47a83c7bf55f1d0", "hex"),
key: {
format: "raw",
data: Buffer.from("1234567890abcdef12345678"),
algorithm: { name: "AES-CMAC" },
extractable: true,
keyUsages: ["sign", "verify"],
},
},
],
import: [
{
name: "raw",
format: "raw",
data: Buffer.from("1234567890abcdef12345678"),
algorithm: "AES-CMAC",
extractable: true,
keyUsages: ["sign", "verify"],
},
{
name: "jwk",
format: "jwk",
data: {
kty: "oct",
alg: "A192CMAC",
k: "MTIzNDU2Nzg5MGFiY2RlZjEyMzQ1Njc4",
ext: true,
key_ops: ["sign", "verify"],
},
algorithm: "AES-CMAC",
extractable: true,
keyUsages: ["sign", "verify"],
},
],
}
};
const AES128GCM = {
name: "AES-128-GCM",
actions: {
generateKey: [
{
algorithm: { name: "AES-GCM", length: 128 },
extractable: true,
keyUsages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"],
},
],
encrypt: [
{
algorithm: {
name: "AES-GCM",
iv: Buffer.from("1234567890ab"),
},
data: Buffer.from("test message"),
encData: Buffer.from("68d645649ddf8152a253304d698185072f28cdcf7644ac6064bcb240", "hex"),
key: {
format: "raw",
data: Buffer.from("1234567890abcdef"),
algorithm: { name: "AES-GCM" },
extractable: true,
keyUsages: ["encrypt", "decrypt"],
},
},
],
import: [
{
name: "raw",
format: "raw",
data: Buffer.from("1234567890abcdef"),
algorithm: "AES-GCM",
extractable: true,
keyUsages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"],
},
{
name: "jwk",
format: "jwk",
data: {
kty: "oct",
alg: "A128GCM",
k: "MTIzNDU2Nzg5MGFiY2RlZg",
ext: true,
key_ops: ["encrypt", "decrypt", "wrapKey", "unwrapKey"],
},
algorithm: "AES-GCM",
extractable: true,
keyUsages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"],
},
],
}
};
const AES192GCM = {
name: "AES-192-GCM",
actions: {
generateKey: [
{
algorithm: { name: "AES-GCM", length: 192 },
extractable: true,
keyUsages: ["encrypt", "decrypt"],
},
],
encrypt: [
{
algorithm: {
name: "AES-GCM",
iv: Buffer.from("1234567890ab"),
},
data: Buffer.from("test message"),
encData: Buffer.from("d8eab579ed2418f41ca9c4567226f54cb391d3ca2cb6819dace35691", "hex"),
key: {
format: "raw",
data: Buffer.from("1234567890abcdef12345678"),
algorithm: { name: "AES-GCM" },
extractable: true,
keyUsages: ["encrypt", "decrypt"],
},
},
],
import: [
{
name: "raw",
format: "raw",
data: Buffer.from("1234567890abcdef12345678"),
algorithm: "AES-GCM",
extractable: true,
keyUsages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"],
},
{
name: "jwk",
format: "jwk",
data: {
kty: "oct",
alg: "A192GCM",
k: "MTIzNDU2Nzg5MGFiY2RlZjEyMzQ1Njc4",
ext: true,
key_ops: ["encrypt", "decrypt", "wrapKey", "unwrapKey"],
},
algorithm: "AES-GCM",
extractable: true,
keyUsages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"],
},
],
}
};
const AES256GCM = {
name: "AES-256-GCM",
actions: {
generateKey: [
{
algorithm: { name: "AES-GCM", length: 256 },
extractable: true,
keyUsages: ["encrypt", "decrypt"],
},
],
encrypt: [
{
algorithm: {
name: "AES-GCM",
iv: Buffer.from("1234567890ab"),
},
data: Buffer.from("test message"),
encData: Buffer.from("f961f2aadbe689ffce86fcaf2619ab647950afcf19e55b71b857c79d", "hex"),
key: {
format: "raw",
data: Buffer.from("1234567890abcdef1234567809abcdef"),
algorithm: { name: "AES-GCM" },
extractable: true,
keyUsages: ["encrypt", "decrypt"],
},
},
],
import: [
{
name: "raw",
format: "raw",
data: Buffer.from("1234567890abcdef1234567890abcdef"),
algorithm: "AES-GCM",
extractable: true,
keyUsages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"],
},
{
name: "jwk",
format: "jwk",
data: {
kty: "oct",
alg: "A256GCM",
k: "MTIzNDU2Nzg5MGFiY2RlZjEyMzQ1Njc4OTBhYmNkZWY",
ext: true,
key_ops: ["encrypt", "decrypt", "wrapKey", "unwrapKey"],
},
algorithm: "AES-GCM",
extractable: true,
keyUsages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"],
},
],
}
};
const AES128KW = {
name: "AES-128-KW",
actions: {
generateKey: [
{
algorithm: { name: "AES-KW", length: 128 },
extractable: true,
keyUsages: ["wrapKey", "unwrapKey"],
},
],
wrapKey: [
{
key: {
format: "raw",
algorithm: "AES-KW",
data: Buffer.from("000102030405060708090A0B0C0D0E0F", "hex"),
extractable: true,
keyUsages: ["wrapKey", "unwrapKey"],
},
wKey: {
format: "raw",
data: Buffer.from("00112233445566778899AABBCCDDEEFF", "hex"),
algorithm: "AES-KW",
extractable: true,
keyUsages: ["wrapKey", "unwrapKey"],
},
algorithm: {
name: "AES-KW",
},
wrappedKey: Buffer.from("1FA68B0A8112B447AEF34BD8FB5A7B829D3E862371D2CFE5", "hex"),
},
],
import: [
{
name: "raw",
format: "raw",
data: Buffer.from("1234567890abcdef12345678"),
algorithm: "AES-KW",
extractable: true,
keyUsages: ["wrapKey", "unwrapKey"],
},
{
name: "jwk",
format: "jwk",
data: {
kty: "oct",
alg: "A192KW",
k: "MTIzNDU2Nzg5MGFiY2RlZjEyMzQ1Njc4",
ext: true,
key_ops: ["wrapKey", "unwrapKey"],
},
algorithm: "AES-KW",
extractable: true,
keyUsages: ["wrapKey", "unwrapKey"],
},
],
},
};
const AES192KW = {
name: "AES-192-KW",
actions: {
generateKey: [
{
algorithm: { name: "AES-KW", length: 192 },
extractable: true,
keyUsages: ["wrapKey", "unwrapKey"],
},
],
wrapKey: [
{
key: {
format: "raw",
algorithm: "AES-KW",
data: Buffer.from("000102030405060708090A0B0C0D0E0F1011121314151617", "hex"),
extractable: true,
keyUsages: ["wrapKey", "unwrapKey"],
},
wKey: {
format: "raw",
data: Buffer.from("00112233445566778899AABBCCDDEEFF0001020304050607", "hex"),
algorithm: "AES-KW",
extractable: true,
keyUsages: ["wrapKey", "unwrapKey"],
},
algorithm: {
name: "AES-KW",
},
wrappedKey: Buffer.from("031D33264E15D33268F24EC260743EDCE1C6C7DDEE725A936BA814915C6762D2", "hex"),
},
],
import: [
{
name: "raw",
format: "raw",
data: Buffer.from("1234567890abcdef12345678"),
algorithm: "AES-KW",
extractable: true,
keyUsages: ["wrapKey", "unwrapKey"],
},
{
name: "jwk",
format: "jwk",
data: {
kty: "oct",
alg: "A192KW",
k: "MTIzNDU2Nzg5MGFiY2RlZjEyMzQ1Njc4",
ext: true,
key_ops: ["wrapKey", "unwrapKey"],
},
algorithm: "AES-KW",
extractable: true,
keyUsages: ["wrapKey", "unwrapKey"],
},
],
},
};
const AES256KW = {
name: "AES-256-KW",
actions: {
generateKey: [
{
algorithm: { name: "AES-KW", length: 256 },
extractable: true,
keyUsages: ["wrapKey", "unwrapKey"],
},
],
wrapKey: [
{
key: {
format: "raw",
algorithm: "AES-KW",
data: Buffer.from("000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F", "hex"),
extractable: true,
keyUsages: ["wrapKey", "unwrapKey"],
},
wKey: {
format: "raw",
data: Buffer.from("00112233445566778899AABBCCDDEEFF000102030405060708090A0B0C0D0E0F", "hex"),
algorithm: "AES-KW",
extractable: true,
keyUsages: ["wrapKey", "unwrapKey"],
},
algorithm: {
name: "AES-KW",
},
wrappedKey: Buffer.from("28C9F404C4B810F4CBCCB35CFB87F8263F5786E2D80ED326CBC7F0E71A99F43BFB988B9B7A02DD21", "hex"),
},
],
import: [
{
name: "raw",
format: "raw",
data: Buffer.from("1234567890abcdef1234567890abcdef"),
algorithm: "AES-KW",
extractable: true,
keyUsages: ["wrapKey", "unwrapKey"],
},
{
name: "jwk",
format: "jwk",
data: {
kty: "oct",
alg: "A256KW",
k: "MTIzNDU2Nzg5MGFiY2RlZjEyMzQ1Njc4OTBhYmNkZWY",
ext: true,
key_ops: ["wrapKey", "unwrapKey"],
},
algorithm: "AES-KW",
extractable: true,
keyUsages: ["wrapKey", "unwrapKey"],
},
],
},
};
const AES128ECB = {
name: "AES-128-ECB",
actions: {
generateKey: [
{
algorithm: { name: "AES-ECB", length: 128 },
extractable: true,
keyUsages: ["encrypt", "decrypt"],
},
],
encrypt: [
{
algorithm: {
name: "AES-ECB",
},
data: pvtsutils.Convert.FromUtf8String("test message"),
encData: pvtsutils.Convert.FromHex("c6ec2f91a9f48e10062ae41e86cb299f"),
key: {
format: "raw",
data: pvtsutils.Convert.FromUtf8String("1234567890abcdef"),
algorithm: { name: "AES-ECB" },
extractable: true,
keyUsages: ["encrypt", "decrypt"],
},
},
],
import: [
{
name: "raw",
format: "raw",
data: pvtsutils.Convert.FromUtf8String("1234567890abcdef"),
algorithm: "AES-ECB",
extractable: true,
keyUsages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"],
},
{
name: "jwk",
format: "jwk",
data: {
kty: "oct",
alg: "A128ECB",
k: "MTIzNDU2Nzg5MGFiY2RlZg",
ext: true,
key_ops: ["encrypt", "decrypt", "wrapKey", "unwrapKey"],
},
algorithm: "AES-ECB",
extractable: true,
keyUsages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"],
},
],
wrapKey: [
{
key: {
format: "raw",
algorithm: "AES-ECB",
data: pvtsutils.Convert.FromBase64("AQIDBAUGBwgJAAECAwQFBg=="),
extractable: true,
keyUsages: ["wrapKey", "unwrapKey"],
},
wKey: {
format: "raw",
data: pvtsutils.Convert.FromUtf8String("1234567890abcdef"),
algorithm: "AES-ECB",
extractable: true,
keyUsages: ["encrypt", "decrypt"],
},
algorithm: {
name: "AES-ECB",
},
wrappedKey: pvtsutils.Convert.FromHex("039ec14b350bd92efd02dac2c01cdee6ea9953cfbdc067f20f5f47bb4459da79"),
},
],
},
};
const AES192ECB = {
name: "AES-192-ECB",
actions: {
generateKey: [
{
algorithm: { name: "AES-ECB", length: 192 },
extractable: true,
keyUsages: ["encrypt", "decrypt"],
},
],
encrypt: [
{
algorithm: {
name: "AES-ECB",
},
data: pvtsutils.Convert.FromUtf8String("test message"),
encData: pvtsutils.Convert.FromHex("8c9f297827ad6aaa9e7501e79fb45ca5"),
key: {
format: "raw",
data: pvtsutils.Convert.FromUtf8String("1234567890abcdef12345678"),
algorithm: { name: "AES-ECB" },
extractable: true,
keyUsages: ["encrypt", "decrypt"],
},
},
],
import: [
{
name: "raw",
format: "raw",
data: pvtsutils.Convert.FromUtf8String("1234567890abcdef12345678"),
algorithm: "AES-ECB",
extractable: true,
keyUsages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"],
},
{
name: "jwk",
format: "jwk",
data: {
kty: "oct",
alg: "A192ECB",
k: "MTIzNDU2Nzg5MGFiY2RlZjEyMzQ1Njc4",
ext: true,
key_ops: ["encrypt", "decrypt", "wrapKey", "unwrapKey"],
},
algorithm: "AES-ECB",
extractable: true,
keyUsages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"],
},
],
},
};
const AES256ECB = {
name: "AES-256-ECB",
actions: {
generateKey: [
{
algorithm: { name: "AES-ECB", length: 256 },
extractable: true,
keyUsages: ["encrypt", "decrypt"],
},
],
encrypt: [
{
algorithm: {
name: "AES-ECB",
},
data: pvtsutils.Convert.FromUtf8String("test message"),
encData: pvtsutils.Convert.FromHex("84ccef71a364b112eb2b3b8b99587a95"),
key: {
format: "raw",
data: pvtsutils.Convert.FromUtf8String("1234567890abcdef1234567809abcdef"),
algorithm: { name: "AES-ECB" },
extractable: true,
keyUsages: ["encrypt", "decrypt"],
},
},
],
import: [
{
name: "raw",
format: "raw",
data: pvtsutils.Convert.FromUtf8String("1234567890abcdef1234567890abcdef"),
algorithm: "AES-ECB",
extractable: true,
keyUsages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"],
},
{
name: "jwk",
format: "jwk",
data: {
kty: "oct",
alg: "A256ECB",
k: "MTIzNDU2Nzg5MGFiY2RlZjEyMzQ1Njc4OTBhYmNkZWY",
ext: true,
key_ops: ["encrypt", "decrypt", "wrapKey", "unwrapKey"],
},
algorithm: "AES-ECB",
extractable: true,
keyUsages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"],
},
],
},
};
const RSAPSS = {
name: "RSA-PSS",
actions: {
generateKey: ["SHA-1", "SHA-256", "SHA-384", "SHA-512"].map((hash) => {
return {
name: hash,
algorithm: {
name: "RSA-PSS",
hash,
publicExponent: new Uint8Array([1, 0, 1]),
modulusLength: 1024,
},
extractable: false,
keyUsages: ["sign", "verify"],
};
}),
sign: [
{
algorithm: {
name: "RSA-PSS",
saltLength: 64,
},
data: new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8, 9, 0]),
signature: pvtsutils.Convert.FromBase64("OYz/7fv71ELOs5kuz5IiYq1NsXuOazl22xqIFjiY++hYFzJMWaR+ZI0WPoMOifvb1PNKmdQ4dY+QbpYC1vdzlAKfkLe22l5htLyQaXzjD/yeMZYrL0KmrabC9ayL6bxrMW+ccePStkbrF1Jn0LT09l22aX/r1y3SPrl0b+zwo/Q="),
key: {
publicKey: {
format: "jwk",
algorithm: { name: "RSA-PSS", hash: "SHA-256" },
data: {
alg: "PS256",
e: "AQAB",
ext: true,
key_ops: ["verify"],
kty: "RSA",
n: "vqpvdxuyZ6rKYnWTj_ZzDBFZAAAlpe5hpoiYHqa2j5kK7v8U5EaPY2bLib9m4B40j-n3FV9xUCGiplWdqMJJKT-4PjGO5E3S4N9kjFhu57noYT7z7302J0sJXeoFbXxlgE-4G55Oxlm52ID2_RJesP5nzcGTriQwoRbrJP5OEt0",
},
extractable: true,
keyUsages: ["verify"],
},
privateKey: {
format: "jwk",
algorithm: { name: "RSA-PSS", hash: "SHA-256" },
data: {
alg: "PS256",
d: "AkeIWJywp9OfYsj0ECsKmhDVBw55ZL_yU-rbIrashQ_31P6gsc_0I-SVN1rd8Hz79OJ_rTY8ZRBZ4PIyFdPoyvuo5apHdAHH6riJKxDHWPxhE-ReNVEPSTiF1ry8DSe5zC7w9BLnH_QM8bkN4cOnvgqrg7EbrGWomAGJVvoRwOM",
dp: "pOolqL7HwnmWLn7GDX8zGkm0Q1IAj-ouBL7ZZbaTm3wETLtwu-dGsQheEdzP_mfL_CTiCAwGuQBcSItimD0DdQ",
dq: "FTSY59AnkgmB7TsErWNBE3xlVB_pMpE2xWyCBCz96gyDOUOFDz8vlSV-clhjawJeRd1n30nZOPSBtOHozhwZmQ",
e: "AQAB",
ext: true,
key_ops: ["sign"],
kty: "RSA",
n: "vqpvdxuyZ6rKYnWTj_ZzDBFZAAAlpe5hpoiYHqa2j5kK7v8U5EaPY2bLib9m4B40j-n3FV9xUCGiplWdqMJJKT-4PjGO5E3S4N9kjFhu57noYT7z7302J0sJXeoFbXxlgE-4G55Oxlm52ID2_RJesP5nzcGTriQwoRbrJP5OEt0",
p: "6jFtmBJJQFIlQUXXZYIgvH70Y9a03oWKjNuF2veb5Zf09EtLNE86NpnIm463OnoHJPW0m8wHFXZZfcYVTIPR_w",
q: "0GttDMl1kIzSV2rNzGXpOS8tUqr5Lz0EtVZwIb9GJPMmJ0P3gZ801zEgZZ4-esU7cLUf-BSZEAmfnKA80G2jIw",
qi: "FByTxX4G2eXkk1xe0IuiEv7I5NS-CnFyp8iB4XLG0rabnfcIZFKpf__X0sNyVOAVo5-jJMuUYjCRTdaXNAWhkg",
},
extractable: true,
keyUsages: ["sign"],
},
},
},
],
},
};
const RSAOAEP = {
name: "RSA-OAEP",
actions: {
generateKey: ["SHA-1", "SHA-256", "SHA-384", "SHA-512"].map((hash) => {
return {
name: hash,
algorithm: {
name: "RSA-OAEP",
hash,
publicExponent: new Uint8Array([1, 0, 1]),
modulusLength: 1024,
},
extractable: false,
keyUsages: ["encrypt", "decrypt"],
};
}),
encrypt: [
{
name: "with label",
algorithm: {
name: "RSA-OAEP",
label: new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8]),
},
data: new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8]),
encData: pvtsutils.Convert.FromBase64("aHu8PBZuctYecfINKgUdB8gBoLyUUFxTZDTzTHUk9KKxtYywYml48HoijBG5DyaIWUUbOIdPgap9C8pFG2iYShQnE9Aj3gzKLHacBbFw1P79+Ei/Tm0j/THiXqCplBZC4dIp4jhTDepmdrlXZcY0slmjG+h8h8TpSmWKP3pEGGk="),
key: {
publicKey: {
format: "jwk",
algorithm: { name: "RSA-OAEP", hash: "SHA-256" },
data: {
alg: "RSA-OAEP-256",
e: "AQAB",
ext: true,
key_ops: ["encrypt"],
kty: "RSA",
n: "vqpvdxuyZ6rKYnWTj_ZzDBFZAAAlpe5hpoiYHqa2j5kK7v8U5EaPY2bLib9m4B40j-n3FV9xUCGiplWdqMJJKT-4PjGO5E3S4N9kjFhu57noYT7z7302J0sJXeoFbXxlgE-4G55Oxlm52ID2_RJesP5nzcGTriQwoRbrJP5OEt0",
},
extractable: true,
keyUsages: ["encrypt"],
},
privateKey: {
format: "jwk",
algorithm: { name: "RSA-OAEP", hash: "SHA-256" },
data: {
alg: "RSA-OAEP-256",
d: "AkeIWJywp9OfYsj0ECsKmhDVBw55ZL_yU-rbIrashQ_31P6gsc_0I-SVN1rd8Hz79OJ_rTY8ZRBZ4PIyFdPoyvuo5apHdAHH6riJKxDHWPxhE-ReNVEPSTiF1ry8DSe5zC7w9BLnH_QM8bkN4cOnvgqrg7EbrGWomAGJVvoRwOM",
dp: "pOolqL7HwnmWLn7GDX8zGkm0Q1IAj-ouBL7ZZbaTm3wETLtwu-dGsQheEdzP_mfL_CTiCAwGuQBcSItimD0DdQ",
dq: "FTSY59AnkgmB7TsErWNBE3xlVB_pMpE2xWyCBCz96gyDOUOFDz8vlSV-clhjawJeRd1n30nZOPSBtOHozhwZmQ",
e: "AQAB",
ext: true,
key_ops: ["decrypt"],
kty: "RSA",
n: "vqpvdxuyZ6rKYnWTj_ZzDBFZAAAlpe5hpoiYHqa2j5kK7v8U5EaPY2bLib9m4B40j-n3FV9xUCGiplWdqMJJKT-4PjGO5E3S4N9kjFhu57noYT7z7302J0sJXeoFbXxlgE-4G55Oxlm52ID2_RJesP5nzcGTriQwoRbrJP5OEt0",
p: "6jFtmBJJQFIlQUXXZYIgvH70Y9a03oWKjNuF2veb5Zf09EtLNE86NpnIm463OnoHJPW0m8wHFXZZfcYVTIPR_w",