Expand description

Webcrypto TS

Test codecov

A minimal ESM based, no dependency, typescript wrapper for the Web Crypto API. Supports both nodejs and browser Web Crypto.

Algorithms are split into their own modules, which enforces consumption of cryptographic materials from the same algorithm. API follows entirely with the Web Crypto API, but removes the need for specifying every argument (secure defaults and inferred key usages). Keys are also proxied to make it easier to use with cryptographic operations.

Install

npm i @nfen/webcrypto-ts

Proxied Keys and Methods

All generated keys are wrapped in a Proxy object, which allows for executing methods specific to each key within a small wrapper.

For example, we can generate an ECDSA keypair and sign directly off the privateKey.

import * as ECDSA from "@nfen/webcrypto-ts/lib/ec/ecdsa";
const keyPair = await ECDSA.generateKeyPair();
const message = new TextEncoder().encode("a message");
const signature = await keyPair.privateKey.sign({ hash: "SHA-512" }, message);

We can still use the WebCrypto based API too. Access any CryptoKey or CryptoKeyPair by using self on the key.

const signature = await ECDSA.sign(keyPair.privateKey.self, { hash: "SHA-512" }, message);

Examples

Many more examples in the Documentation.

ECDSA

import * as ECDSA from "@nfen/webcrypto-ts/lib/ec/ecdsa";
const keyPair = await ECDSA.generateKeyPair();

const message = new TextEncoder().encode("a message");
const signature = await keyPair.privateKey.sign({ hash: "SHA-512" }, message);

const pubJwk = await keyPair.publicKey.exportKey("jwk");
const publicKey = await ECDSA.importKey(
"jwk",
pubJwk,
{ namedCurve: "P-512" },
true,
["verify"]
);

const isVerified = await publicKey.verify(
{ hash: "SHA-512" },
signature,
message
);

RSA-OAEP

import * as RSA_OAEP from "@nfen/webcrypto-ts/lib/rsa/rsa_oaep";
import * as AES_CBC from "@nfen/webcrypto-ts/lib/aes/aes_cbc";
import * as Random from "@nfen/webcrypto-ts/lib/random";

const kek = await RSA_OAEP.generateKeyPair(
{
hash: "SHA-512",
modulusLength: 4096,
publicExponent: new Uint8Array([0x01, 0x00, 0x01]),
},
true,
["wrapKey", "unwrapKey"]
);
const dek = await AES_CBC.generateKey();
const label = await Random.getValues(8);
const wrappedCbcKey = await kek.publicKey.wrapKey("raw", dek.self, { label });

AES-GCM

import * as AES_GCM from "@nfen/webcrypto-ts/lib/aes/aes_gcm";
import { IV } from "@nfen/webcrypto-ts/lib/random";

const iv = await IV.generate();
const key = await AES_GCM.generateKey();
const message = "a message";
const cipherText = await key.encrypt(
{ iv },
new TextEncoder().encode("a message")
);
console.assert(
new TextDecoder().decode(await key.decrypt({ iv }, message)) === message
);

Modules

All AES related modes and functions

Code related to AES_CBC mode

Code related to AES_CTR mode

Code related to AES_GCM mode

Code related to AES_KW mode

Shared code for AES

All elliptic curve algorithms

Code related to ECDH

Code related to ECDSA

Shared code for EC

Code related to HMAC

webcrypto-ts main entry point

All key derivation functions

Code related to HKDF

Code related to PBKDF2

Shared code for KDF

Key usages and allowed formats

Enforced parameters for algorithms

Code related to proxying CryptoKey and CryptoKeyPair

Cryptographically strong random values.

All RSA algorithms

Code related to RSA_OAEP

Code related to RSA_PSS

Code related to RSASSA_PKCS1_v1_5

Shared code for RSA

All SHA algorithms

Code related to SHA_1

Code related to SHA_256

Code related to SHA_384

Code related to SHA_512

Shared code for SHA

Wrapper for node/browser webcrypto