From 15ae1e53dd8e7264a293820626073cc9768e4be5 Mon Sep 17 00:00:00 2001 From: tamaina Date: Sun, 3 Mar 2024 11:33:17 +0000 Subject: [PATCH] :v: --- dist/index.cjs | 15 ++++++++++++--- dist/index.mjs | 14 +++++++++++--- dist/utils.d.ts | 4 ++++ src/draft/verify.ts | 4 ++-- src/pem/spki.ts | 2 +- src/utils.ts | 12 ++++++++++++ test/performance/draft.js | 28 ++++++++++++++++++++++++++-- 7 files changed, 68 insertions(+), 11 deletions(-) diff --git a/dist/index.cjs b/dist/index.cjs index 79f1e3a..05a57de 100644 --- a/dist/index.cjs +++ b/dist/index.cjs @@ -45,6 +45,7 @@ __export(src_exports, { UnknownSignatureHeaderFormatError: () => UnknownSignatureHeaderFormatError, asn1ToArrayBuffer: () => asn1ToArrayBuffer, checkClockSkew: () => checkClockSkew, + decodeBase64ToUint8Array: () => decodeBase64ToUint8Array, decodePem: () => decodePem, detectAndVerifyAlgorithm: () => detectAndVerifyAlgorithm, digestHashAlgosForDecoding: () => digestHashAlgosForDecoding, @@ -268,6 +269,14 @@ function encodeArrayBufferToBase64(buffer) { const binary = String.fromCharCode(...uint8Array); return btoa(binary); } +function decodeBase64ToUint8Array(base64) { + const binary = atob(base64); + const uint8Array = new Uint8Array(binary.length); + for (let i = 0; i < binary.length; i++) { + uint8Array[i] = binary.charCodeAt(i); + } + return uint8Array; +} // src/pem/pkcs8.ts var import_asn1js3 = __toESM(require("@lapo/asn1js"), 1); @@ -471,7 +480,7 @@ function genSignOrVerifyAlgorithm(parsed, defaults = { if (!algorithm) throw new SpkiParseError("Unknown algorithm"); if (algorithm === "RSASSA-PKCS1-v1_5") { - return { name: "RSASSA-PKCS1-v1_5" }; + return "RSASSA-PKCS1-v1_5"; } if (algorithm === "EC") { return { @@ -970,7 +979,6 @@ function detectAndVerifyAlgorithm(algorithm, publicKey, errorLogger) { // src/draft/verify.ts var ncrypto2 = __toESM(require("node:crypto"), 1); -var import_base642 = __toESM(require("@lapo/asn1js/base64.js"), 1); function verifyDraftSignature(parsed, publicKeyPem, errorLogger) { const publicKey = ncrypto2.createPublicKey(publicKeyPem); try { @@ -988,7 +996,7 @@ async function webVerifyDraftSignature(parsed, publicKeyPem, errorLogger) { try { const parsedSpki = parsePublicKey(publicKeyPem); const publicKey = await crypto.subtle.importKey("spki", parsedSpki.der, genKeyImportParams(parsedSpki), false, ["verify"]); - const verify2 = await crypto.subtle.verify(genSignOrVerifyAlgorithm(parsedSpki), publicKey, import_base642.default.decode(parsed.params.signature), new TextEncoder().encode(parsed.signingString)); + const verify2 = await crypto.subtle.verify(genSignOrVerifyAlgorithm(parsedSpki), publicKey, decodeBase64ToUint8Array(parsed.params.signature), new TextEncoder().encode(parsed.signingString)); return verify2; } catch (e) { if (errorLogger) @@ -1013,6 +1021,7 @@ async function webVerifyDraftSignature(parsed, publicKeyPem, errorLogger) { UnknownSignatureHeaderFormatError, asn1ToArrayBuffer, checkClockSkew, + decodeBase64ToUint8Array, decodePem, detectAndVerifyAlgorithm, digestHashAlgosForDecoding, diff --git a/dist/index.mjs b/dist/index.mjs index 73fc88d..b13c915 100644 --- a/dist/index.mjs +++ b/dist/index.mjs @@ -172,6 +172,14 @@ function encodeArrayBufferToBase64(buffer) { const binary = String.fromCharCode(...uint8Array); return btoa(binary); } +function decodeBase64ToUint8Array(base64) { + const binary = atob(base64); + const uint8Array = new Uint8Array(binary.length); + for (let i = 0; i < binary.length; i++) { + uint8Array[i] = binary.charCodeAt(i); + } + return uint8Array; +} // src/pem/pkcs8.ts import ASN13 from "@lapo/asn1js"; @@ -375,7 +383,7 @@ function genSignOrVerifyAlgorithm(parsed, defaults = { if (!algorithm) throw new SpkiParseError("Unknown algorithm"); if (algorithm === "RSASSA-PKCS1-v1_5") { - return { name: "RSASSA-PKCS1-v1_5" }; + return "RSASSA-PKCS1-v1_5"; } if (algorithm === "EC") { return { @@ -874,7 +882,6 @@ function detectAndVerifyAlgorithm(algorithm, publicKey, errorLogger) { // src/draft/verify.ts import * as ncrypto2 from "node:crypto"; -import Base642 from "@lapo/asn1js/base64.js"; function verifyDraftSignature(parsed, publicKeyPem, errorLogger) { const publicKey = ncrypto2.createPublicKey(publicKeyPem); try { @@ -892,7 +899,7 @@ async function webVerifyDraftSignature(parsed, publicKeyPem, errorLogger) { try { const parsedSpki = parsePublicKey(publicKeyPem); const publicKey = await crypto.subtle.importKey("spki", parsedSpki.der, genKeyImportParams(parsedSpki), false, ["verify"]); - const verify2 = await crypto.subtle.verify(genSignOrVerifyAlgorithm(parsedSpki), publicKey, Base642.decode(parsed.params.signature), new TextEncoder().encode(parsed.signingString)); + const verify2 = await crypto.subtle.verify(genSignOrVerifyAlgorithm(parsedSpki), publicKey, decodeBase64ToUint8Array(parsed.params.signature), new TextEncoder().encode(parsed.signingString)); return verify2; } catch (e) { if (errorLogger) @@ -916,6 +923,7 @@ export { UnknownSignatureHeaderFormatError, asn1ToArrayBuffer, checkClockSkew, + decodeBase64ToUint8Array, decodePem, detectAndVerifyAlgorithm, digestHashAlgosForDecoding, diff --git a/dist/utils.d.ts b/dist/utils.d.ts index f973dae..a8363c8 100644 --- a/dist/utils.d.ts +++ b/dist/utils.d.ts @@ -28,3 +28,7 @@ export declare function genASN1Length(length: number | bigint): Uint8Array; * For web */ export declare function encodeArrayBufferToBase64(buffer: ArrayBuffer): string; +/** + * for Web + */ +export declare function decodeBase64ToUint8Array(base64: string): Uint8Array; diff --git a/src/draft/verify.ts b/src/draft/verify.ts index e80373c..1776f76 100644 --- a/src/draft/verify.ts +++ b/src/draft/verify.ts @@ -2,7 +2,7 @@ import { detectAndVerifyAlgorithm } from '../shared/verify.js'; import * as ncrypto from 'node:crypto'; import type { ParsedDraftSignature } from '../types.js'; import { genKeyImportParams, genSignOrVerifyAlgorithm, parsePublicKey } from '../pem/spki.js'; -import Base64 from '@lapo/asn1js/base64.js'; +import { decodeBase64ToUint8Array } from '../utils.js'; export function verifyDraftSignature(parsed: ParsedDraftSignature['value'], publicKeyPem: string, errorLogger?: ((message: any) => any)) { const publicKey = ncrypto.createPublicKey(publicKeyPem); @@ -25,7 +25,7 @@ export async function webVerifyDraftSignature(parsed: ParsedDraftSignature['valu const parsedSpki = parsePublicKey(publicKeyPem); const publicKey = await crypto.subtle.importKey('spki', parsedSpki.der, genKeyImportParams(parsedSpki), false, ['verify']); - const verify = await crypto.subtle.verify(genSignOrVerifyAlgorithm(parsedSpki), publicKey, Base64.decode(parsed.params.signature), (new TextEncoder()).encode(parsed.signingString)); + const verify = await crypto.subtle.verify(genSignOrVerifyAlgorithm(parsedSpki), publicKey, decodeBase64ToUint8Array(parsed.params.signature), (new TextEncoder()).encode(parsed.signingString)); return verify; } catch (e) { if (errorLogger) errorLogger(e); diff --git a/src/pem/spki.ts b/src/pem/spki.ts index f19002f..8d14b0f 100644 --- a/src/pem/spki.ts +++ b/src/pem/spki.ts @@ -225,7 +225,7 @@ export function genSignOrVerifyAlgorithm( if (!algorithm) throw new SpkiParseError('Unknown algorithm'); if (algorithm === 'RSASSA-PKCS1-v1_5') { - return { name: 'RSASSA-PKCS1-v1_5' }; + return 'RSASSA-PKCS1-v1_5'; } if (algorithm === 'EC') { return { diff --git a/src/utils.ts b/src/utils.ts index d9e9b1a..e07e6e0 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -126,3 +126,15 @@ export function encodeArrayBufferToBase64(buffer: ArrayBuffer): string { const binary = String.fromCharCode(...uint8Array); return btoa(binary); } + +/** + * for Web + */ +export function decodeBase64ToUint8Array(base64: string): Uint8Array { + const binary = atob(base64); + const uint8Array = new Uint8Array(binary.length); + for (let i = 0; i < binary.length; i++) { + uint8Array[i] = binary.charCodeAt(i); + } + return uint8Array; +} diff --git a/test/performance/draft.js b/test/performance/draft.js index a5a55a0..813dd44 100644 --- a/test/performance/draft.js +++ b/test/performance/draft.js @@ -57,6 +57,11 @@ console.log('Performance test, TRYES:', TRYES); } logPerf('web Sign RSA4096, SHA-256', process.hrtime(start)); } + { + const start = process.hrtime(); + await Promise.all(Array(TRYES).fill().map(() => signAsDraftToRequestWeb(request, { keyId: 'test', privateKeyPem: rsa4096.privateKey }, basicIncludeHeaders, { hashAlgorithm: 'sha256' }))); + logPerf('web(Promise.all) Sign RSA4096, SHA-256', process.hrtime(start)); + } /** * Ed25519 @@ -75,6 +80,11 @@ console.log('Performance test, TRYES:', TRYES); } logPerf('web Sign Ed25519', process.hrtime(start)); } + { + const start = process.hrtime(); + await Promise.all(Array(TRYES).fill().map(() => signAsDraftToRequestWeb(request, { keyId: 'test', privateKeyPem: ed25519.privateKey }, basicIncludeHeaders, { hashAlgorithm: null }))); + logPerf('web(Promise.all) Sign Ed25519', process.hrtime(start)); + } } /** @@ -97,7 +107,6 @@ console.log('Performance test, TRYES:', TRYES); } logPerf(testCase, process.hrtime(start)); } - { const testCase = 'web Verify RSA4096, SHA-256'; const start = process.hrtime(); @@ -109,6 +118,14 @@ console.log('Performance test, TRYES:', TRYES); } logPerf(testCase, process.hrtime(start)); } + { + const testCase = 'web(Promise.all) Verify RSA4096, SHA-256'; + const start = process.hrtime(); + await Promise.all(Array(TRYES).fill().map(() => + webVerifyDraftSignature(parsed.value, rsa4096.publicKey) + .then(r => r ? true : Promise.reject(new Error('failed'))))); + logPerf(testCase, process.hrtime(start)); + } request.headers = lcObjectKey(request.headers); const parsedJ = httpSignature.parseRequest(request); @@ -145,7 +162,6 @@ console.log('Performance test, TRYES:', TRYES); } logPerf(testCase, process.hrtime(start)); } - { const testCase = 'web Verify Ed25519'; const start = process.hrtime(); @@ -158,6 +174,14 @@ console.log('Performance test, TRYES:', TRYES); const end = performance.now(); logPerf(testCase, process.hrtime(start)); } + { + const testCase = 'web(Promise.all) Verify Ed25519'; + const start = process.hrtime(); + await Promise.all(Array(TRYES).fill().map(() => + webVerifyDraftSignature(parsed.value, ed25519.publicKey) + .then(r => r ? true : Promise.reject(new Error('failed'))))); + logPerf(testCase, process.hrtime(start)); + } request.headers = lcObjectKey(request.headers); const parsedJ = httpSignature.parseRequest(request);