Node.js 加密与安全
crypto 加密模块
Node.js 使用 C/C++ 实现加密算法,通过 crypto 模块暴露为 JavaScript 接口。
js
const crypto = require('crypto')const crypto = require('crypto')哈希算法
哈希函数是单向不可逆的,输出固定长度。
js
// MD5
const hash = crypto.createHash('md5')
hash.update('123456')
console.log(hash.digest('hex')) // 十六进制字符串
// SHA256
const sha256 = crypto.createHash('sha256')
sha256.update('123456')
console.log(sha256.digest('hex'))// MD5
const hash = crypto.createHash('md5')
hash.update('123456')
console.log(hash.digest('hex')) // 十六进制字符串
// SHA256
const sha256 = crypto.createHash('sha256')
sha256.update('123456')
console.log(sha256.digest('hex'))应用场景:
- 密码加密存储(避免明文)
- 文件完整性校验(对比前后端 MD5)
HMAC
带密钥的哈希算法:
js
crypto.createHmac('md5', 'secretKey').update('str').digest('hex')crypto.createHmac('md5', 'secretKey').update('str').digest('hex')对称加密
使用相同的密钥进行加密和解密:
js
const iv = Buffer.from(crypto.randomBytes(16)) // 初始化向量
const key = crypto.randomBytes(32) // 密钥
// 加密 (AES-256-CBC)
const cipher = crypto.createCipheriv('aes-256-cbc', key, iv)
cipher.update('小满zs', 'utf-8', 'hex')
const encrypted = cipher.final('hex')
// 解密
const decipher = crypto.createDecipheriv('aes-256-cbc', key, iv)
decipher.update(encrypted, 'hex')
const decrypted = decipher.final('utf-8')const iv = Buffer.from(crypto.randomBytes(16)) // 初始化向量
const key = crypto.randomBytes(32) // 密钥
// 加密 (AES-256-CBC)
const cipher = crypto.createCipheriv('aes-256-cbc', key, iv)
cipher.update('小满zs', 'utf-8', 'hex')
const encrypted = cipher.final('hex')
// 解密
const decipher = crypto.createDecipheriv('aes-256-cbc', key, iv)
decipher.update(encrypted, 'hex')
const decrypted = decipher.final('utf-8')非对称加密
使用公钥/私钥对:
js
// 生成 RSA 密钥对
const { privateKey, publicKey } = crypto.generateKeyPairSync('rsa', {
modulusLength: 2048
})
const text = '小满zs'
// 公钥加密
const encrypted = crypto.publicEncrypt(publicKey, Buffer.from(text))
// 私钥解密
const decrypted = crypto.privateDecrypt(privateKey, encrypted)
console.log(decrypted.toString())// 生成 RSA 密钥对
const { privateKey, publicKey } = crypto.generateKeyPairSync('rsa', {
modulusLength: 2048
})
const text = '小满zs'
// 公钥加密
const encrypted = crypto.publicEncrypt(publicKey, Buffer.from(text))
// 私钥解密
const decrypted = crypto.privateDecrypt(privateKey, encrypted)
console.log(decrypted.toString())Cookie
解决 HTTP 无状态问题。
Node.js 原生操作
js
// 设置 Cookie
res.setHeader('Set-Cookie', ['name=hny', 'age=18'])
// 获取 Cookie
req.headers.cookie// 设置 Cookie
res.setHeader('Set-Cookie', ['name=hny', 'age=18'])
// 获取 Cookie
req.headers.cookieExpress 中使用
安装中间件:
bash
npm install cookie-parsernpm install cookie-parserjs
const cookieParser = require('cookie-parser')
app.use(cookieParser())
// 设置 Cookie
res.cookie('name', 'hny', {
maxAge: 24 * 60 * 60 * 1000, // 过期时间(毫秒)
httpOnly: true, // 禁止客户端修改
path: '/', // 允许访问的路径
domain: 'localhost' // 允许访问的域名
})
// 获取 Cookie
req.cookies.nameconst cookieParser = require('cookie-parser')
app.use(cookieParser())
// 设置 Cookie
res.cookie('name', 'hny', {
maxAge: 24 * 60 * 60 * 1000, // 过期时间(毫秒)
httpOnly: true, // 禁止客户端修改
path: '/', // 允许访问的路径
domain: 'localhost' // 允许访问的域名
})
// 获取 Cookie
req.cookies.nameSession
Session 数据存在服务器,通过 Cookie 传递 Session ID。
express-session
bash
npm install express-sessionnpm install express-sessionjs
const session = require('express-session')
app.use(session({
name: 'session', // Cookie 名称
keys: ['key1', 'key2'], // 密钥数组
maxAge: 24 * 60 * 60 * 1000
}))
// 设置 Session
req.session.username = 'hny'
// 获取 Session
req.session.usernameconst session = require('express-session')
app.use(session({
name: 'session', // Cookie 名称
keys: ['key1', 'key2'], // 密钥数组
maxAge: 24 * 60 * 60 * 1000
}))
// 设置 Session
req.session.username = 'hny'
// 获取 Session
req.session.usernameCookie vs Session
| 特性 | Cookie | Session |
|---|---|---|
| 存放位置 | 客户端浏览器 | 服务器 |
| 安全性 | 不安全,可被分析篡改 | 相对安全 |
| 大小限制 | 约 4KB | 无限制 |
| 失效 | 可设置过期时间 | 浏览器关闭失效 |
| 禁用 | 可被禁用 | 不受影响 |
JWT
JSON Web Token,三段式加密字符串:
xxxxx.yyyyy.zzzzz
头信息. 载荷. 签名xxxxx.yyyyy.zzzzz
头信息. 载荷. 签名bash
npm install jsonwebtokennpm install jsonwebtokenjs
const jwt = require('jsonwebtoken')
// 生成 Token
const token = jwt.sign(
{ username: 'zhangsan', age: 25 },
'secretKey',
{ expiresIn: 60 * 60 } // 过期时间(秒)
)
// 验证 Token
jwt.verify(token, 'secretKey', (err, data) => {
if (err) return console.log('无效 Token')
console.log(data)
})const jwt = require('jsonwebtoken')
// 生成 Token
const token = jwt.sign(
{ username: 'zhangsan', age: 25 },
'secretKey',
{ expiresIn: 60 * 60 } // 过期时间(秒)
)
// 验证 Token
jwt.verify(token, 'secretKey', (err, data) => {
if (err) return console.log('无效 Token')
console.log(data)
})
Cao Note