Skip to content

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())

解决 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.cookie

Express 中使用 ​

安装中间件:

bash
npm install cookie-parser
npm install cookie-parser
js
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.name
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.name

Session ​

Session 数据存在服务器,通过 Cookie 传递 Session ID。

express-session ​

bash
npm install express-session
npm install express-session
js
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.username
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.username
特性CookieSession
存放位置客户端浏览器服务器
安全性不安全,可被分析篡改相对安全
大小限制约 4KB无限制
失效可设置过期时间浏览器关闭失效
禁用可被禁用不受影响

JWT ​

JSON Web Token,三段式加密字符串:

xxxxx.yyyyy.zzzzz
 头信息.  载荷.  签名
xxxxx.yyyyy.zzzzz
 头信息.  载荷.  签名
bash
npm install jsonwebtoken
npm install jsonwebtoken
js
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)
})