UNPKG

@peculiar/webcrypto-test

Version:
1,358 lines (1,343 loc) 115 kB
/** * 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",