@kohanajs/mod-crypto
Version:
Web Crypto Helper for KohanaJS
68 lines (54 loc) • 2.19 kB
JavaScript
const { Buffer } = require('node:buffer');
const { TextEncoder } = require('node:util');
const { subtle } = require('node:crypto').webcrypto;
const CRYPTO_ALGORITHMS = {
RSASSA_PKCS1_v1_5: 'RSASSA-PKCS1-v1_5',
RSA_PSS: 'RSA-PSS',
ECDSA: 'ECDSA',
HMAC: 'HMAC',
RSA_OAEP: 'RSA-OAEP',
AES_CTR: 'AES-CTR',
AES_CBC: 'AES-CBC',
AES_GCM: 'AES-GCM',
SHA1: 'SHA-1',
SHA256: 'SHA-256',
SHA384: 'SHA-384',
SHA512: 'SHA-512',
ECDH: 'ECDH',
HKDF: 'HKDF',
PBKDF2: 'PBKDF2',
AES_KW: 'AES-KW',
};
const fs = require('fs').promises;
const defaultSignAlgorithm = { name: CRYPTO_ALGORITHMS.HMAC, hash: CRYPTO_ALGORITHMS.SHA256 };
class HelperCrypto {
static CRYPTO_ALGORITHMS = CRYPTO_ALGORITHMS;
static async makeSignKey(filePath, algorithm = defaultSignAlgorithm) {
const key = await subtle.generateKey(algorithm, true, ['sign', 'verify']);
const jwk = await subtle.exportKey('jwk', key);
const text = `module.exports=${JSON.stringify(jwk)}`;
await fs.writeFile(filePath, text);
return jwk;
}
static async sign(jwk, data, algorithm = defaultSignAlgorithm, expire=0, timestamp= 0) {
const key = await subtle.importKey('jwk', jwk, algorithm, true, ['sign', 'verify']);
const expire_ms = expire * 1000;
const strExpire = (expire ? `::${ Math.floor(((timestamp || Date.now()) + expire_ms) / 1000) }` : '');
const buffer = new TextEncoder().encode(data + strExpire);
const sign = await subtle.sign(algorithm, key, buffer);
return Buffer.from(sign).toString('base64') + strExpire;
}
static async verify(jwk, sign, data, algorithm = defaultSignAlgorithm, timestamp=0) {
const signs = sign.split('::');
if(signs[1]){
const expire_ms = parseInt(signs[1]) * 1000;
if((timestamp || Date.now()) > expire_ms)return false;
}
const strExpire = signs[1] ? `::${signs[1]}` : '';
const key = await subtle.importKey('jwk', jwk, algorithm, true, ['sign', 'verify']);
const bufferSign = Buffer.from(signs[0], "base64");
const bufferData = new TextEncoder().encode(data + strExpire);
return subtle.verify(algorithm, key, bufferSign, bufferData);
}
}
module.exports = HelperCrypto;