Release Crypto Tools 0.2.0
Verify / verify (push) Canceled after 0s

This commit is contained in:
2026-09-02 10:40:23 +02:00
parent 4b75f819e2
commit 82bb01b13f
37 changed files with 3673 additions and 140 deletions
+107
View File
@@ -0,0 +1,107 @@
import { Integer, Null, ObjectIdentifier, OctetString, Sequence } from "asn1js";
function buffer(bytes: Uint8Array): ArrayBuffer {
return bytes.buffer.slice(
bytes.byteOffset,
bytes.byteOffset + bytes.byteLength,
) as ArrayBuffer;
}
export function encryptedPkcs8Pem(bytes: Uint8Array): string {
const binary = Array.from(bytes, (value) => String.fromCharCode(value)).join(
"",
);
const body =
btoa(binary)
.match(/.{1,64}/gu)
?.join("\n") ?? "";
return `-----BEGIN ENCRYPTED PRIVATE KEY-----\n${body}\n-----END ENCRYPTED PRIVATE KEY-----`;
}
export async function encryptedPkcs8(password: string): Promise<Uint8Array> {
const pair = await crypto.subtle.generateKey(
{ name: "ECDSA", namedCurve: "P-256" },
true,
["sign", "verify"],
);
const privateKey = new Uint8Array(
await crypto.subtle.exportKey("pkcs8", pair.privateKey),
);
try {
return await encryptedPbes2Payload(password, privateKey);
} finally {
privateKey.fill(0);
}
}
export async function encryptedPbes2Payload(
password: string,
plaintext: Uint8Array,
): Promise<Uint8Array> {
const salt = Uint8Array.from({ length: 16 }, (_, index) => index + 1);
const iv = Uint8Array.from({ length: 16 }, (_, index) => 32 - index);
const material = await crypto.subtle.importKey(
"raw",
new TextEncoder().encode(password),
"PBKDF2",
false,
["deriveKey"],
);
const key = await crypto.subtle.deriveKey(
{
name: "PBKDF2",
hash: "SHA-256",
salt: buffer(salt),
iterations: 12_000,
},
material,
{ name: "AES-CBC", length: 256 },
false,
["encrypt"],
);
const ciphertext = new Uint8Array(
await crypto.subtle.encrypt(
{ name: "AES-CBC", iv: buffer(iv) },
key,
buffer(plaintext),
),
);
const encoded = new Sequence({
value: [
new Sequence({
value: [
new ObjectIdentifier({ value: "1.2.840.113549.1.5.13" }),
new Sequence({
value: [
new Sequence({
value: [
new ObjectIdentifier({ value: "1.2.840.113549.1.5.12" }),
new Sequence({
value: [
new OctetString({ valueHex: buffer(salt) }),
new Integer({ value: 12_000 }),
new Sequence({
value: [
new ObjectIdentifier({ value: "1.2.840.113549.2.9" }),
new Null(),
],
}),
],
}),
],
}),
new Sequence({
value: [
new ObjectIdentifier({ value: "2.16.840.1.101.3.4.1.42" }),
new OctetString({ valueHex: buffer(iv) }),
],
}),
],
}),
],
}),
new OctetString({ valueHex: buffer(ciphertext) }),
],
});
return new Uint8Array(encoded.toBER(false));
}