import crypto from 'crypto' const AUTH_MODE = [ 'aes-128-gcm', 'aes-192-gcm', 'aes-256-gcm', 'aes-128-ccm', 'aes-192-ccm', 'aes-256-ccm', 'aes-128-ocb', 'aes-192-ocb', 'aes-256-ocb' ] const VERSION = +process.versions.node.split('.').slice(0, 2).join('.') const KEY_16 = Buffer.alloc(16) function format(buff, encode) { if (encode === void 0 || encode === 'buffer') { return buff } return buff.toString(encode) } // if (!crypto.randomUUID) { crypto.randomUUID = function () { let str = crypto.randomBytes(16).toString('hex') return ( str.slice(0, 8) + '-' + str.slice(8, 12) + '-' + str.slice(12, 16) + '-' + str.slice(16, 20) + '-' + str.slice(-12) ) } } if (!crypto.randomInt) { crypto.randomInt = function (max) { if (max === void 0) { throw new TypeError( '[ERR_INVALID_ARG_TYPE]: The "max" argument must be a safe integer. Received undefined' ) } return ~~(Math.random() * max) } } export { crypto } export const hash = function (mode, data, outEncode) { let sum = crypto.createHash(mode) let isBuffer = Buffer.isBuffer(data) sum.update(data, isBuffer ? 'buffer' : 'utf8') return sum.digest(outEncode || 'hex') } export const hmac = function (mode, data, key, outEncode) { key = key || '' let sum = crypto.createHmac(mode, key) let isBuffer = Buffer.isBuffer(data) sum.update(data, isBuffer ? 'buffer' : 'utf8') return sum.digest(outEncode || 'hex') } export const cipher = function ( mode, data, key = KEY_16, inEncode = 'utf8', outEncode ) { // 10.0.0之后, createCipher方法不推荐使用了 if (VERSION >= 10.5) { return cipheriv(mode, data, key, KEY_16, inEncode, outEncode) } let isBuffer = Buffer.isBuffer(data) inEncode = isBuffer ? 'buffer' : inEncode let _cipher = crypto.createCipher(mode, key) let buff = _cipher.update(data, inEncode) buff = Buffer.concat([buff, _cipher.final()]) if (AUTH_MODE.indexOf(mode) > -1) { buff = Buffer.concat([buff, _cipher.getAuthTag()]) } return format(buff, outEncode) } export const decipher = function ( mode, data, key = KEY_16, inEncode = 'base64', outEncode = 'utf8' ) { // 10.0.0之后, createCipher方法不推荐使用了 if (VERSION >= 10.5) { return decipheriv(mode, data, key, KEY_16, inEncode, outEncode) } let isBuffer = Buffer.isBuffer(data) if (!isBuffer) { data = Buffer.from(data, inEncode) } inEncode = 'buffer' let _decipher = crypto.createDecipher(mode, key) if (AUTH_MODE.indexOf(mode) > -1) { let tag = data.slice(-16) data = data.slice(0, -16) _decipher.setAuthTag(tag) } let buff = _decipher.update(data, inEncode) buff = Buffer.concat([buff, _decipher.final()]) return format(buff, outEncode) } export const cipheriv = function ( mode, data, key = KEY_16, iv = KEY_16, inEncode = 'utf8', outEncode ) { let isBuffer = Buffer.isBuffer(data) inEncode = isBuffer ? 'buffer' : inEncode let _cipher = crypto.createCipheriv(mode, key, iv) let buff = _cipher.update(data, inEncode) buff = Buffer.concat([buff, _cipher.final()]) if (AUTH_MODE.indexOf(mode) > -1) { buff = Buffer.concat([buff, _cipher.getAuthTag()]) } return format(buff, outEncode) } export const decipheriv = function ( mode, data, key = KEY_16, iv = KEY_16, inEncode = 'base64', outEncode = 'utf8' ) { let isBuffer = Buffer.isBuffer(data) if (!isBuffer) { data = Buffer.from(data, inEncode) } inEncode = 'buffer' let _decipher = crypto.createDecipheriv(mode, key, iv) if (AUTH_MODE.indexOf(mode) > -1) { let tag = data.slice(-16) data = data.slice(0, -16) _decipher.setAuthTag(tag) } let buff = _decipher.update(data, inEncode) buff = Buffer.concat([buff, _decipher.final()]) return format(buff, outEncode) }