本文已参与「新人创作礼」活动,一起开启掘金创作之路。
SHA256作为最常用的加密学哈希函数,它的稳定、快速实现可以有效提高应用的安全性。本文在此简单记录以SHA256为主的几个加密学函数在浏览器和Nodejs环境下的原生实现,不依赖任何第三方包。
随机字符串
一个最简单的随机字符串生成方案是
Math.random().toString(36).substring(2)
但这个随机字符串不是加密学安全的!安全的随机字符串生成如下:
Nodejs
特别注意,这里的l不是字符串长度!
const crypto = require('crypto')
const random = l => crypto.randomBytes(l).toString('base64url')
最后的编码方法可以修改为下列值:'ascii', 'utf8', 'utf16le'/'ucs2', 'base64', 'base64url', 'latin1'/'binary', 'hex'
Browser
const base64url = buffer => btoa(String.fromCharCode(...new Uint8Array(buffer))).replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, '')
function random (l) {
const a = new Uint8Array(l)
window.crypto.getRandomValues(a)
return base64url(a)
}
输出base64url编码的随机串,同样这里的l不是字符串长度!。这里的base64url函数下面还要用到。
SHA256
Nodejs
const sha256 = t => crypto.createHash('sha256').update(t).digest('base64url')
同样,可以修改最后输出的编码方式:'ascii', 'utf8', 'utf16le'/'ucs2', 'base64', 'base64url', 'latin1'/'binary', 'hex'
Browser
const enc = new TextEncoder('utf-8')
const base64url = buffer => btoa(String.fromCharCode(...new Uint8Array(buffer))).replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, '')
const sha256 = str => window.crypto.subtle.digest('SHA-256', enc.encode(str)).then(base64url)
特别注意:
window.crypto.subtle只能在安全环境(本机或https)下使用!并请特别注意不同浏览器版本的支持情况。- 这个
sha256函数是异步的,需要await。
HS256
HS256是HMAC with SHA-256的缩写,是一种常用的对称签名方案。
Nodejs
const HS256 = (msg, secret) => crypto.createHmac('sha256', secret).update(msg).digest('base64url')
同样,可以修改最后输出的编码方式:'ascii', 'utf8', 'utf16le'/'ucs2', 'base64', 'base64url', 'latin1'/'binary', 'hex'
Browser
const enc = new TextEncoder('utf-8')
const base64url = buffer => btoa(String.fromCharCode(...new Uint8Array(buffer))).replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, '')
const HS256 = async (str, secret) => {
const key = await window.crypto.subtle.importKey('raw', enc.encode(secret), { name: 'HMAC', hash: { name: 'SHA-256' }},false,['sign', 'verify'])
const signature = await window.crypto.subtle.sign('HMAC', key, enc.encode(str))
return base64url(signature)
}
特别注意:
window.crypto.subtle只能在安全环境(本机或https)下使用!并请特别注意不同浏览器版本的支持情况。- 这个
HS256函数是异步的,需要await。