Skip to content
docs.
WORKSPACE

Your documentation

Explore the project catalog
Localzet ServerАсинхронный PHP-серверTriangleФреймворк и компонентыMIX IDИдентификация и интеграцииHack APIПубличные API хакатонаACNПроект и компонентыUserlay / UserNetПроект и компонентыAxiomПроект и компонентыМесседжинг через почтуПроект и компонентыLWT / JWT / JOSEПроект и компоненты✓Финансовая аналитика KimaiПроект и компонентыМультипарадигмальная БДПроект и компонентыZorin PlatformПроект и компонентыZorin TrustПроект и компонентыFloraScope / VegwatchПроект и компонентыaegis-qДокументация проектаaevumdbДокументация проектаauditДокументация проектаauto-invest-managerАвтотрейдерcaine-companionДокументация проектаcertbot-cloudflareДокументация проектаClusterLocalzet Server / ClustercmdveilДокументация проектаConsolePHP CLICronБиблиотеки Localzet Serverdata-connectorДокументация проектаdevice-controlDevice Controlenn-projectДокументация проектаEventsБиблиотеки Localzet ServerflowsintДокументация проектаforgeДокументация проектаHttpClientБиблиотеки Localzet ServerinterpreterСобственный языкinvariaДокументация проектаkeynotesДокументация проектаknotrouteKnotroutelaravel-personal-analyticsДокументация проектаlocalzet-osДокументация проектаmeridianДокументация проектаMQTTБиблиотеки Localzet Servernano-kernelСобственная ОСNoterДокументация проектаpersonal-analyticsДокументация проектаProxyБиблиотеки Localzet ServerPSRБиблиотеки Localzet ServerPSR-7Библиотеки Localzet Serverrschs-monitorДокументация проектаsemsealДокументация проектаshardsealДокументация проектаSocketIOБиблиотеки Localzet ServerSOCKS5Библиотеки Localzet Serverstandalone-analyticsДокументация проектаstatic-php-cliДокументация проектаStorageБиблиотеки Localzet ServersutureДокументация проектаtempoweaveДокументация проектаttsСинтез речиTunnelБиблиотеки Localzet Serverui-kitUI KitvesperДокументация проектаWebAnalyzerWebAnalyzerzorin-access-brokerДокументация проектаzorin-authority-brokerДокументация проектаzorin-authority-sdk-phpДокументация проектаzorin-authority-sdk-pythonДокументация проектаzorin-authority-sdk-tsДокументация проектаzorin-client-intelДокументация проектаzorin-device-core-aospДокументация проектаzorin-host-agentДокументация проектаzorin-native-labДокументация проектаzorin-nodeДокументация проектаzorin-opsДокументация проектаdonstu-python-sdkДокументация проектаfloortraceFloortraceserver-rsLocalzet Server / Cluster
Catalog
Documentation/LWT / JWT / JOSE

jwt-ts — API

src/encoding.ts

export function base64urlEncode(input: Buffer | string): string

src/encoding.ts

export function base64urlDecode(input: string): Buffer

src/encoding.ts

export function derToJose(signature: Buffer, keySize: number): Buffer

src/encoding.ts

export function joseToDer(signature: Buffer): Buffer

src/errors.ts

export class JWTError extends Error {
constructor(message: string) {
super(message);
this.name = 'JWTError';
}
}

src/errors.ts

export class InvalidSignatureError extends JWTError {
constructor() {
super('Invalid signature');
this.name = 'InvalidSignatureError';
}
}

src/errors.ts

export class TokenExpiredError extends JWTError {
constructor() {
super('Token expired');
this.name = 'TokenExpiredError';
}
}

src/errors.ts

export class NotBeforeError extends JWTError {
constructor() {
super('Token not active yet (nbf)');
this.name = 'NotBeforeError';
}
}

src/errors.ts

export class JWTClaimValidationError extends JWTError {
constructor(message: string) {
super(message);
this.name = 'JWTClaimValidationError';
}
}

src/errors.ts

export class JoseHeaderError extends JWTError {
constructor(message: string) {
super(message);
this.name = 'JoseHeaderError';
}
}

src/header.ts

export type JoseContext = 'jws' | 'jwe' | 'jwt';

src/header.ts

export interface HeaderValidationOptions {
context: JoseContext;
enforceUnknown?: 'reject' | 'ignore';
allowedExtensions?: Set<string>;
expectedTyp?: string | null;
}

src/header.ts

export function validateJoseHeaders(header: { [k: string]: any } | undefined, opts: HeaderValidationOptions)

src/header.ts

export class HeaderValidator {
static validate(header: { [k: string]: any } | undefined, opts: HeaderValidationOptions) {
if (!header) return;
if (typeof header !== 'object') throw new JoseHeaderError('JOSE header must be an object');
const allowed = allowedParamsFor(opts.context);
const allowedExt = opts.allowedExtensions || new Set<string>();
const enforceUnknown = opts.enforceUnknown ?? 'ignore';
if (header.crit !== undefined) {
if (!Array.isArray(header.crit) || !header.crit.every((i: any) => typeof i === 'string')) {
throw new JoseHeaderError('Invalid "crit" header: must be array of strings');
}
for (const critName of header.crit as string[]) {
if (!Object.prototype.hasOwnProperty.call(header, critName)) {
throw new JoseHeaderError(`crit declares ${critName} but it is not present in header`);
}
if (!allowed.has(critName) && !allowedExt.has(critName)) {
throw new JoseHeaderError(`Unsupported critical header parameter: ${critName}`);
}
}
}
for (const k of Object.keys(header)) {
if (allowed.has(k)) continue;
if (allowedExt.has(k)) continue;
if (k === 'x5t#S256') continue;
if (enforceUnknown === 'reject') {
throw new JoseHeaderError(`Unknown JOSE header parameter: ${k}`);
}
}
if (opts.expectedTyp) {
if (header.typ !== undefined && header.typ !== opts.expectedTyp) {
throw new JoseHeaderError(`Unexpected typ header: expected ${opts.expectedTyp}`);
}
}
if (header.cty !== undefined && typeof header.cty !== 'string') {
throw new JoseHeaderError('cty header must be a string when present');
}
}
}

src/jwa.ts

export type Alg =
| 'HS256' | 'HS384' | 'HS512'
| 'RS256' | 'RS384' | 'RS512'
| 'PS256' | 'PS384' | 'PS512'
| 'ES256' | 'ES256K' | 'ES384' | 'ES512'
| 'EdDSA'
| 'none';

src/jwa.ts

export interface Signer {
sign(payload: Buffer, key: crypto.KeyLike | Buffer | string): Buffer | Promise<Buffer>;
verify(payload: Buffer, signature: Buffer, key: crypto.KeyLike | Buffer | string): boolean | Promise<boolean>;
}

src/jwa.ts

export function getSigner(alg: Alg): Signer

src/jwa.ts

export class JWAFactory {
static getSigner(alg: Alg): Signer {
switch (alg) {
case 'HS256': return HMAC('sha256');
case 'HS384': return HMAC('sha384');
case 'HS512': return HMAC('sha512');
case 'RS256': return RSA('sha256', crypto.constants.RSA_PKCS1_PADDING);
case 'RS384': return RSA('sha384', crypto.constants.RSA_PKCS1_PADDING);
case 'RS512': return RSA('sha512', crypto.constants.RSA_PKCS1_PADDING);
case 'PS256': return RSA_PSS('sha256');
case 'PS384': return RSA_PSS('sha384');
case 'PS512': return RSA_PSS('sha512');
case 'ES256': return ECDSA('sha256', 256);
case 'ES256K': return ECDSA('sha256', 256); // secp256k1
case 'ES384': return ECDSA('sha384', 384);
case 'ES512': return ECDSA('sha512', 521);
case 'EdDSA':
return {
sign(payload: Buffer, key) {
return (crypto as any).sign(null, payload, key as crypto.KeyLike) as Buffer;
},
verify(payload: Buffer, signature: Buffer, key) {
return (crypto as any).verify(null, payload, key as crypto.KeyLike, signature) as boolean;
}
};
case 'none':
return {
sign() { return Buffer.alloc(0); },
verify() { return true; }
};
default:
throw new Error(`Unsupported alg ${alg}`);
}
}
}

src/jwe.ts

export async function encryptCompact(plaintext: Buffer | string, recipient: { alg: string; key: any }, headerInput: any = {}, enc: 'A128GCM' | 'A256GCM' | 'A128CBC-HS256' | 'A256CBC-HS512' = 'A256GCM')

src/jwe.ts

export async function decryptCompact(token: string, keyOrLookup: any | ((header: any) => any | Promise<any>))

src/jwe.ts

export async function encryptGeneral(plaintext: Buffer | string, recipients: Array<{ alg: string; key: any; header?: any; }>, protectedHeader: any = {}, unprotectedHeader: any = {}, enc: 'A128GCM' | 'A256GCM' | 'A128CBC-HS256' | 'A256CBC-HS512' = 'A256GCM')

src/jwe.ts

export async function decryptGeneral(jwe: any, keyOrLookup: any | ((header: any) => any | Promise<any>))

src/jwk.ts

export type JWK = { [key: string]: any };

src/jwk.ts

export function jwkToKeyObject(jwk: JWK): crypto.KeyObject

src/jwk.ts

export function keyObjectToJwk(key: crypto.KeyObject): JWK

src/jwk.ts

export function jwkToPEM(jwk: JWK, opts: { private?: boolean } = {}): string

src/jwk.ts

export function pemToJwk(pem: string): JWK

src/jwk.ts

export function jwkThumbprint(jwk: JWK, hash = 'sha256'): string

src/jwk.ts

export class JWKManager {
jwkToKeyObject(jwk: JWK) {
if (!jwk || typeof jwk !== 'object') throw new TypeError('Invalid JWK');
const hasPrivate = !!jwk.d;
try {
if (hasPrivate) return crypto.createPrivateKey({ key: jwk as any, format: 'jwk' });
return crypto.createPublicKey({ key: jwk as any, format: 'jwk' });
} catch (e) {
throw new Error('Failed to convert JWK to KeyObject: ' + (e as Error).message);
}
}
keyObjectToJwk(key: crypto.KeyObject) {
try {
return key.export({ format: 'jwk' }) as JWK;
} catch (e) {
throw new Error('Failed to export KeyObject to JWK: ' + (e as Error).message);
}
}
jwkToPEM(jwk: JWK, opts: { private?: boolean } = {}) {
const keyObj = this.jwkToKeyObject(jwk);
if (opts.private) return keyObj.export({ type: 'pkcs8', format: 'pem' }) as string;
return keyObj.export({ type: 'spki', format: 'pem' }) as string;
}
pemToJwk(pem: string) {
const keyObj = crypto.createPublicKey(pem);
try {
return keyObj.export({ format: 'jwk' }) as JWK;
} catch (e) {
const priv = crypto.createPrivateKey(pem);
return priv.export({ format: 'jwk' }) as JWK;
}
}
jwkThumbprint(jwk: JWK, hash = 'sha256') {
const kty = jwk.kty;
let members: string[] = [];
if (kty === 'RSA') members = ['e', 'kty', 'n'];
else if (kty === 'EC') members = ['crv', 'kty', 'x', 'y'];
else if (kty === 'OKP') members = ['crv', 'kty', 'x'];
else throw new Error('Unsupported JWK kty for thumbprint');
const obj: any = {};
for (const m of members) obj[m] = jwk[m];
const json = JSON.stringify(obj);
const h = crypto.createHash(hash).update(json).digest();
return h.toString('base64').replace(/=/g, '').replace(/\+/g, '-').replace(/\//g, '_');
}
}

src/jwks.ts

export type JWKS = { keys: JWK[] };

src/jwks.ts

export function getJwkByKid(jwks: JWKS | JWK[], kid?: string, alg?: string): JWK | undefined

src/jwks.ts

export function resolveJwkFromHeader(jwks: JWKS | JWK[], header: { kid?: string; alg?: string }): JWK | undefined

src/jwks.ts

export class JWKSResolver {
static getJwkByKid(jwks: JWKS | JWK[], kid?: string, alg?: string) {
const keys = Array.isArray(jwks) ? jwks : (jwks && jwks.keys) || [];
if (!kid && !alg) return keys[0];
let candidates = keys;
if (kid) candidates = candidates.filter(k => k.kid === kid);
if (alg) candidates = candidates.filter(k => {
if (!k.alg) return true;
return k.alg === alg || k.alg === alg.replace('-', '');
});
return candidates[0];
}
static resolveJwkFromHeader(jwks: JWKS | JWK[], header: { kid?: string; alg?: string }) {
return JWKSResolver.getJwkByKid(jwks, header.kid, header.alg);
}
}

src/jws.ts

export type JWSHeader = { alg: Alg; typ?: string; cty?: string; kid?: string; b64?: boolean; crit?: string[];[key: string]: any };

src/jws.ts

export interface SignerInput {
key: any; // PEM, KeyObject or JWK
protectedHeader?: Partial<JWSHeader>;
header?: { [key: string]: any } | undefined; // unprotected header
}

src/jws.ts

export async function signCompact(payload: object | string | Buffer, signer: SignerInput): Promise<string>

src/jws.ts

export async function verifyCompact(token: string, keyOrLookup: any | ((header: JWSHeader) => any | Promise<any>), options: { expectedAlg?: Alg; expectedTyp?: string; detachedPayload?: Buffer | string } = {}): Promise<{ header: JWSHeader; payload: any }>

src/jws.ts

export interface GeneralJWS {
protected?: { [key: string]: any };
header?: { [key: string]: any };
signature: string;
}

src/jws.ts

export async function signGeneral(payload: object | string | Buffer, signers: SignerInput[], opts: { detached?: boolean } = {}): Promise<{ payload: string; signatures: GeneralJWS[] }>

src/jws.ts

export async function verifyGeneral(obj: { payload: string; signatures: GeneralJWS[] }, keyOrLookup: any | ((header: any) => any | Promise<any>), options: { expectedTyp?: string; detachedPayload?: Buffer | string } = {}): Promise<{ payload: any; verified: boolean }>

src/jwt.ts

export type JWTPayload = { [key: string]: any };

src/jwt.ts

export type JWTHeader = { alg: Alg; typ?: string; kid?: string;[key: string]: any };

src/jwt.ts

export interface SignOptions {
alg?: Alg;
typ?: string;
kid?: string;
iat?: boolean; // add issued at
exp?: number | null; // seconds from now
}

src/jwt.ts

export interface VerifyOptions {
algorithms?: Alg[];
issuer?: string | string[];
subject?: string | string[];
audience?: string | string[];
jti?: string;
typ?: string; // expected typ header
ignoreExpiration?: boolean;
clockTolerance?: number; // seconds
}

src/jwt.ts

export async function sign(payload: JWTPayload, key: any, options: SignOptions = {}): Promise<string>

src/jwt.ts

export function decode(token: string, options: { complete?: boolean } = {}): any

src/jwt.ts

export async function verify(token: string, key: any | ((header: JWTHeader) => any | Promise<any>), options: VerifyOptions = {}): Promise<JWTPayload>