175 lines
3.8 KiB
JavaScript
175 lines
3.8 KiB
JavaScript
|
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)
|
||
|
}
|