@ivujs/i-utils
Version:
前端模块化 JavaScript 工具库
96 lines (93 loc) • 3.3 kB
JavaScript
import { generateKey, generateIv, OUTPUT, PADDING, MODE, encrypt, decrypt } from './sm4.mjs';
/**
* sm4 加密
* @param {string} str 字符串
* @param {string} key 秘钥
* @param {Object} options 配置
* @returns {string} 加密后的字符串
*/
function sm4Encrypt(str, key, options) {
_validateSM4Options(options, "encrypt");
return encrypt(str, key, options);
}
/**
* sm4 解密
* @param {string} str 字符串
* @param {string} key 秘钥
* @param {Object} options 配置
* @returns {string} 解密后的数据
*/
function sm4Decrypt(str, key, options) {
_validateSM4Options(options, "decrypt");
return decrypt(str, key, options);
}
/**
* 生成sm4的key
* @param {string} inputFormat 输入类型 可以任意字符串,其中固定的uint8array、array、hex这3个字符串,会对应生成类型数据
* @returns {SM4DataType} 生成的key
*/
const generateSM4Key = generateKey;
/**
* 生成sm4的iv
* @param {string} inputFormat 输入类型 可以任意字符串,其中固定的uint8array、array、hex这3个字符串,会对应生成类型数据
* @returns {SM4DataType} 生成的iv
*/
const generateSM4Iv = generateIv;
/**
* 校验SM4配置参数的合法性
* @param options 配置项
* @param operation 操作类型(encrypt/decrypt)
*/
function _validateSM4Options(options = {}, operation) {
const { mode = MODE.ECB, iv } = options;
// 1. 校验模式是否合法
const validModes = Object.values(MODE);
if (!validModes.includes(mode)) {
throw new TypeError(`sm4${operation}:unsupported encryption mode "${mode}", supports only ${validModes.join("/")}`);
}
// 2. CBC模式必须传IV
if (mode === MODE.CBC && !iv) {
throw new TypeError(`sm4${operation}:the CBC mode must be inputted with an IV (initialization vector)`);
}
// 3. ECB模式禁止传IV(避免误用)
if (mode === MODE.ECB && iv !== undefined) {
throw new TypeError(`sm4${operation}: the ECB mode does not require an IV to be passed in. Please do not pass the iv parameter`);
}
// 4. 校验IV长度(如果传了IV)
if (iv) {
let ivLength;
if (typeof iv === "string") {
// hex字符串:16字节对应32位hex
ivLength = iv.length === 32 ? 16 : iv.length;
}
else if (iv instanceof ArrayBuffer) {
ivLength = iv.byteLength;
}
else if (iv instanceof Uint8Array) {
ivLength = iv.length;
}
else if (Array.isArray(iv)) {
ivLength = iv.length;
}
else {
ivLength = 0;
}
if (ivLength !== 16) {
throw new TypeError(`sm4${operation}:IV must be 16 bytes in length, and the current length is ${ivLength}`);
}
}
// 5. 校验填充模式(仅允许pkcs#7)
if (options.padding && options.padding !== String(PADDING)) {
throw new TypeError(`sm4${operation}: only pkcs#7 padding mode is supported, currently being input ${String(options.padding)}`);
}
}
// sm4的配置
const SM4 = {
// sm4的模式
MODE: MODE,
// sm4的填充
PADDING: PADDING,
// sm4的输出
OUTPUT: OUTPUT,
};
export { SM4, generateSM4Iv, generateSM4Key, sm4Decrypt, sm4Encrypt };