koa-api/libs/crypto.js

84 lines
1.9 KiB
JavaScript

var crypto = require('crypto')
/**
* @param {Number} len
*/
var random = (len = 32) => {
var buf = crypto.randomBytes(len)
return buf.toString('hex')
}
/**
*
* @param {string} str
*/
var sha256 = (str, tostr = 'base64') => {
return crypto.createHash('sha256').update(str).digest(tostr)
}
/**
*
* @param {string} str
*/
var genPassHash = (str) => {
var hash = random(16)
var pass = sha256(str + hash)
return `$${hash}$${pass}`
}
/**
*
* @param {string} plain
* @param {string} hash
*/
var comparePass = (plain, hash) => {
var match = hash.match(/^\$(.+?)\$(.+)$/)
if (match == null || match.length < 3 || !match[1] || !match[2]) return false
var pass = sha256(plain + match[1])
if (pass === match[2]) return true
return false
}
const pbkdf2 = (pass, salt, count, len, tostr = false) => {
let hlen = crypto.createHash('sha256').update('').digest().length
let blockCount = Math.ceil(len / hlen)
let s256 = (s) => { return crypto.createHash('sha256').update(s).digest() }
let out = []
for (let i = 0; i < blockCount; i++) {
let loopBuf = Buffer.alloc(4)
loopBuf.writeInt32BE(i)
let saltBuf = Buffer.from(salt)
let last = Buffer.concat([saltBuf, loopBuf], saltBuf.length + loopBuf.length)
let passBuf = Buffer.from(pass)
last = s256(Buffer.concat([passBuf, last], passBuf.length + last.length))
let xor = Buffer.from(last)
for (let j = 1; j < count; j++) {
last = s256(Buffer.concat([passBuf, last], passBuf.length + last.length))
xor = last.map((t, idx) => {
return t ^ xor[idx]
})
}
out.push(xor)
}
let olen = 0
for (let i in out) {
olen += out[i].length
}
let raw = Buffer.concat([...out], olen)
if (!tostr) {
return raw.slice(0, len)
} else {
return Buffer.from(raw.slice(0, len)).toString('hex')
}
}
module.exports = {
random,
sha256,
genPassHash,
comparePass,
pbkdf2
}