@sparta-utils/crypto-util
Version:
一个支持多种加密算法的加密工具库,涵盖 AES、RSA、SM2、SM3、SM4、SHA、HMAC、MD5、Base64、JWT 等,适用于日常加解密、签名验签、摘要、Token 管理等场景。
482 lines (462 loc) • 13.1 kB
JavaScript
import CryptoJS$1 from 'crypto-js';
import smCrypto from 'sm-crypto';
import { Base64 } from 'js-base64';
/**
* 使用 AES 加密文本(默认使用 CBC 模式)
* @param text 明文
* @param options 配置项
*/
function encrypt$3(text, options) {
const { key, iv = '', mode = 'cbc', padding = 'pkcs7' } = options;
const keyUtf8 = CryptoJS$1.enc.Utf8.parse(key);
const ivUtf8 = CryptoJS$1.enc.Utf8.parse(iv);
const encrypted = CryptoJS$1.AES.encrypt(text, keyUtf8, {
iv: iv ? ivUtf8 : undefined,
mode: mode === 'cbc' ? CryptoJS$1.mode.CBC : CryptoJS$1.mode.ECB,
padding: padding === 'pkcs7' ? CryptoJS$1.pad.Pkcs7 : CryptoJS$1.pad.NoPadding
});
return encrypted.toString();
}
/**
* 使用 AES 解密文本
* @param encryptedText 密文
* @param options 配置项
*/
function decrypt$3(encryptedText, options) {
const { key, iv = '', mode = 'cbc', padding = 'pkcs7' } = options;
const keyUtf8 = CryptoJS$1.enc.Utf8.parse(key);
const ivUtf8 = CryptoJS$1.enc.Utf8.parse(iv);
const decrypted = CryptoJS$1.AES.decrypt(encryptedText, keyUtf8, {
iv: iv ? ivUtf8 : undefined,
mode: mode === 'cbc' ? CryptoJS$1.mode.CBC : CryptoJS$1.mode.ECB,
padding: padding === 'pkcs7' ? CryptoJS$1.pad.Pkcs7 : CryptoJS$1.pad.NoPadding
});
return decrypted.toString(CryptoJS$1.enc.Utf8);
}
var AESUtil = /*#__PURE__*/Object.freeze({
__proto__: null,
decrypt: decrypt$3,
encrypt: encrypt$3
});
const { sm4 } = smCrypto;
/**
* 将字符串 key 转成 Uint8Array,且长度必须是16字节
* @param key 字符串密钥,必须16字符长度
* @throws 如果长度不对会抛异常
*/
function formatKey(key) {
if (key.length !== 16) {
throw new Error('SM4 密钥必须是16个字符(128位)');
}
const arr = new Uint8Array(16);
for (let i = 0; i < 16; i++) {
arr[i] = key.charCodeAt(i);
}
return arr;
}
/**
* SM4 加密(ECB模式,默认输出hex字符串)
*/
function encrypt$2(text, key) {
const keyBytes = formatKey(key);
return sm4.encrypt(text, keyBytes);
}
/**
* SM4 解密
*/
function decrypt$2(encrypted, key) {
const keyBytes = formatKey(key);
return sm4.decrypt(encrypted, keyBytes);
}
var SM4Util = /*#__PURE__*/Object.freeze({
__proto__: null,
decrypt: decrypt$2,
encrypt: encrypt$2
});
var _a;
// 判断是否为 Node.js 环境
const isNode$3 = typeof process !== 'undefined' && !!((_a = process.versions) === null || _a === void 0 ? void 0 : _a.node);
/**
* 生成 RSA 公钥和私钥
*/
function generateKeyPair$1() {
if (isNode$3) {
const crypto = require('crypto');
const { publicKey, privateKey } = crypto.generateKeyPairSync('rsa', {
modulusLength: 2048,
publicKeyEncoding: { type: 'spki', format: 'pem' },
privateKeyEncoding: { type: 'pkcs8', format: 'pem' }
});
return { publicKey, privateKey };
}
else {
const { JSEncrypt } = require('jsencrypt');
const crypt = new JSEncrypt({ default_key_size: '2048' });
crypt.getKey();
return {
publicKey: crypt.getPublicKey() || '',
privateKey: crypt.getPrivateKey() || ''
};
}
}
/**
* 使用 RSA 公钥加密
*/
function encrypt$1(data, publicKey) {
if (isNode$3) {
const crypto = require('crypto');
return crypto.publicEncrypt(publicKey, Buffer.from(data)).toString('base64');
}
else {
const { JSEncrypt } = require('jsencrypt');
const encryptor = new JSEncrypt();
encryptor.setPublicKey(publicKey);
return encryptor.encrypt(data) || '';
}
}
/**
* 使用 RSA 私钥解密
*/
function decrypt$1(encryptedData, privateKey) {
if (isNode$3) {
const crypto = require('crypto');
return crypto
.privateDecrypt(privateKey, Buffer.from(encryptedData, 'base64'))
.toString('utf8');
}
else {
const { JSEncrypt } = require('jsencrypt');
const decryptor = new JSEncrypt();
decryptor.setPrivateKey(privateKey);
return decryptor.decrypt(encryptedData) || '';
}
}
/**
* 使用 RSA 私钥对数据进行签名
*/
function sign$2(data, privateKey) {
if (isNode$3) {
const crypto = require('crypto');
const sign = crypto.createSign('RSA-SHA256');
sign.update(data);
sign.end();
return sign.sign(privateKey, 'base64');
}
else {
const { JSEncrypt } = require('jsencrypt');
const signer = new JSEncrypt();
signer.setPrivateKey(privateKey);
return signer.sign(data, CryptoJS.SHA256, 'sha256') || '';
}
}
/**
* 使用 RSA 公钥验证签名
*/
function verify$2(data, signature, publicKey) {
if (isNode$3) {
const crypto = require('crypto');
const verify = crypto.createVerify('RSA-SHA256');
verify.update(data);
verify.end();
return verify.verify(publicKey, signature, 'base64');
}
else {
const { JSEncrypt } = require('jsencrypt');
const verifier = new JSEncrypt();
verifier.setPublicKey(publicKey);
return verifier.verify(data, signature, CryptoJS.SHA256, 'sha256');
}
}
var RSAUtil = /*#__PURE__*/Object.freeze({
__proto__: null,
decrypt: decrypt$1,
encrypt: encrypt$1,
generateKeyPair: generateKeyPair$1,
sign: sign$2,
verify: verify$2
});
const { sm2 } = smCrypto;
/**
* 生成 SM2 公私钥对
*/
function generateKeyPair() {
const [publicKey, privateKey] = sm2.generateKeyPairHex();
return { publicKey, privateKey };
}
/**
* SM2 加密
*/
function encrypt(text, publicKey) {
return sm2.doEncrypt(text, publicKey, 1);
}
/**
* SM2 解密
*/
function decrypt(encrypted, privateKey) {
return sm2.doDecrypt(encrypted, privateKey, 1);
}
/**
* SM2 签名
*/
function sign$1(data, privateKey) {
return sm2.doSignature(data, privateKey);
}
/**
* SM2 验签
*/
function verify$1(data, signature, publicKey) {
return sm2.doVerifySignature(data, signature, publicKey);
}
var SM2Util = /*#__PURE__*/Object.freeze({
__proto__: null,
decrypt: decrypt,
encrypt: encrypt,
generateKeyPair: generateKeyPair,
sign: sign$1,
verify: verify$1
});
/**
* 计算 SHA256 哈希
* @param data 输入字符串
* @returns 返回十六进制字符串
*/
function sha256(data) {
return CryptoJS$1.SHA256(data).toString(CryptoJS$1.enc.Hex);
}
/**
* 计算 SHA512 哈希
* @param data 输入字符串
* @returns 返回十六进制字符串
*/
function sha512(data) {
return CryptoJS$1.SHA512(data).toString(CryptoJS$1.enc.Hex);
}
var SHAUtil = /*#__PURE__*/Object.freeze({
__proto__: null,
sha256: sha256,
sha512: sha512
});
let nodeCrypto$1 = null;
const isNode$2 = typeof process !== 'undefined' &&
process.versions != null &&
process.versions.node != null;
if (isNode$2) {
try {
nodeCrypto$1 = require('crypto');
}
catch (_a) {
nodeCrypto$1 = null;
}
}
/**
* HMAC 计算,支持 sha256 和 sha512
* @param algorithm 'sha256' | 'sha512'
* @param key 密钥
* @param data 待签名数据
* @returns 十六进制字符串
*/
function hmac(algorithm, key, data) {
if (nodeCrypto$1) {
// Node.js 环境用内置 crypto
return nodeCrypto$1.createHmac(algorithm, key).update(data).digest('hex');
}
else {
// 浏览器环境用 crypto-js
let hashFunc;
if (algorithm === 'sha256') {
hashFunc = CryptoJS$1.HmacSHA256;
}
else if (algorithm === 'sha512') {
hashFunc = CryptoJS$1.HmacSHA512;
}
else {
throw new Error('Unsupported algorithm for HMAC: ' + algorithm);
}
const result = hashFunc(data, key);
return result.toString(CryptoJS$1.enc.Hex);
}
}
var HMACUtil = /*#__PURE__*/Object.freeze({
__proto__: null,
hmac: hmac
});
function sm3(data) {
return smCrypto.sm3(data);
}
let nodeCrypto = null;
// 判断是否是Node环境(简单判断)
const isNode$1 = typeof process !== 'undefined' &&
process.versions != null &&
process.versions.node != null;
if (isNode$1) {
try {
nodeCrypto = require('crypto');
}
catch (_a) {
nodeCrypto = null;
}
}
/**
* 使用 MD5 哈希明文
* @param text 明文
*/
function md5(data) {
if (nodeCrypto) {
// Node.js 环境用原生crypto
return nodeCrypto.createHash('md5').update(data).digest('hex');
}
else {
// 浏览器环境用crypto-js
return CryptoJS$1.MD5(data).toString();
}
}
/**
* Base64 编码,兼容浏览器和 Node
*/
function encodeBase64(data) {
return Base64.encode(data);
}
/**
* Base64 解码,兼容浏览器和 Node
*/
function decodeBase64(data) {
return Base64.decode(data);
}
// jwt.ts
let jsonwebtoken = null;
let jose = null;
// 判断是否运行在 Node.js 环境
const isNode = typeof process !== 'undefined' &&
process.versions != null &&
process.versions.node != null;
// 加载 Node.js 端的 jsonwebtoken 模块
if (isNode) {
try {
jsonwebtoken = require('jsonwebtoken');
}
catch (err) {
console.warn('[CryptoUtil] jsonwebtoken not available in Node.js:', err);
}
}
else {
// 加载浏览器端的 jose 模块(由打包工具处理)
try {
jose = require('jose');
}
catch (err) {
console.warn('[CryptoUtil] jose not available in browser:', err);
}
}
/**
* 生成 JWT Token(支持 Node.js 和浏览器)
* @param payload 负载数据,例如 { uid: 123 }
* @param secret 签名密钥
* @param options 可选参数,如 { expiresIn: '1h' }
* @returns JWT token 字符串
*/
async function sign(payload, secret, options = {}) {
if (isNode && jsonwebtoken) {
// Node.js 下使用 jsonwebtoken 库
return jsonwebtoken.sign(payload, secret, options);
}
if (jose) {
// 浏览器下使用 jose 库
const { SignJWT, importJWK } = jose;
const enc = new TextEncoder();
const key = enc.encode(secret);
// Create a JWK (JSON Web Key) for HS256
const jwk = {
kty: 'oct',
k: jose.base64url.encode(key),
alg: 'HS256',
use: 'sig'
};
const jwt = new SignJWT(payload)
.setProtectedHeader({ alg: 'HS256' }) // 指定加密算法
.setIssuedAt() // 设置签发时间
.setExpirationTime(options.expiresIn || '1h'); // 设置过期时间
const cryptoKey = await importJWK(jwk, 'HS256');
return jwt.sign(cryptoKey);
}
throw new Error('JWT signing not supported in this environment.');
}
/**
* 验证 JWT Token 的合法性并提取 payload(支持 Node.js 和浏览器)
* @param token JWT 字符串
* @param secret 验证密钥
* @returns 解密后的 payload 对象
*/
async function verify(token, secret) {
if (isNode && jsonwebtoken) {
// Node.js 验证
const result = jsonwebtoken.verify(token, secret);
if (typeof result === 'string') {
throw new Error('JWT payload is a string, expected an object.');
}
return result;
}
if (jose) {
const { jwtVerify, importJWK, base64url } = jose;
const enc = new TextEncoder();
const key = enc.encode(secret);
// Create a JWK (JSON Web Key) for HS256
const jwk = {
kty: 'oct',
k: base64url.encode(key),
alg: 'HS256',
use: 'sig'
};
const cryptoKey = await importJWK(jwk, 'HS256');
const result = await jwtVerify(token, cryptoKey);
return result.payload;
}
throw new Error('JWT verification not supported in this environment.');
}
/**
* 解码 JWT Token(不验证签名,仅解析 payload)
* @param token JWT 字符串
* @returns 解析后的 payload 对象或 null
*/
function decode(token) {
if (isNode && jsonwebtoken) {
// Node.js 使用 jsonwebtoken.decode
const decoded = jsonwebtoken.decode(token);
if (typeof decoded === 'string') {
return null;
}
return decoded;
}
try {
// 浏览器中使用 base64 解码中间段
const payloadBase64 = token.split('.')[1];
const json = atob(payloadBase64);
return JSON.parse(json);
}
catch (err) {
console.warn('[CryptoUtil] Failed to decode JWT:', err);
return null;
}
}
var JWTUtil = /*#__PURE__*/Object.freeze({
__proto__: null,
decode: decode,
sign: sign,
verify: verify
});
class CryptoUtil {
}
CryptoUtil.aes = AESUtil;
CryptoUtil.rsa = RSAUtil;
CryptoUtil.sm2 = SM2Util;
CryptoUtil.sm4 = SM4Util;
CryptoUtil.sha = SHAUtil;
CryptoUtil.hmac = HMACUtil;
CryptoUtil.sm3 = sm3;
CryptoUtil.md5 = md5;
CryptoUtil.jwt = JWTUtil;
CryptoUtil.base64 = {
encode: encodeBase64,
decode: decodeBase64
};
export { CryptoUtil };
//# sourceMappingURL=index.esm.js.map