使用 aes-256-cbc 在 Node.js 中加密和解密数据
本教程旨在教您如何在 Node.js 中加密和解密数据。
这里提供的方法非常简单易懂,编写的目的是为了帮助其他程序员和开发人员学习如何在应用程序中加密数据。
这种加密方法可用于文件、消息或应用程序需要加密的任何其他数据。
在本教程中,提供的加密和解密方法基于 AES-256 算法,我们之所以使用它,是因为它是当今最流行的加密算法之一,并且以其安全性而闻名。
注意:AES-256 算法是一种对称密钥算法,这意味着加密和解密使用同一个密钥。这与非对称密钥算法不同,非对称密钥算法使用公钥进行加密,使用私钥进行解密。
先决条件
- Node.js
- NPM 或纱线
- 掌握 Javascript 知识
入门
首先,你需要创建一个新的项目文件夹,并在其中初始化 npm 或 yarn。为此,请在终端中运行以下命令:
本教程中我将使用 yarn,但如果您愿意,也可以使用 npm。
mkdir nodejs-encryption
cd nodejs-encryption
yarn init -y
这将创建一个名为 nodejs-encryption 的新文件夹,并在其中初始化 yarn。-y 标志用于跳过交互模式并使用默认值。
安装依赖项
要安装依赖项,请在终端中运行以下命令:
yarn add express dotenv
yarn add -D nodemon
这将安装 express 和 dotenv 模块,nodemon 模块将安装在 devDependencies 中。
修改 package.json 文件
我们将使用 package.json 文件中的模块类型,以便在我们的项目中启用 ES6 模块,同时我们还将启动脚本和开发脚本添加到 package.json 文件中的 scripts 对象中。
"type": "module",
"scripts": {
"start": "node server.js",
"dev": "nodemon server.js"
}
创建配置文件
要创建配置文件,请在项目根目录下创建一个名为 config.js 的新文件。在该文件中,您将存储密钥、密钥初始化向量 (IV) 和加密方法。密钥和密钥 IV 用于生成密钥哈希值,该哈希值用于加密和解密。加密方法用于指定要使用的加密算法。在本教程中,我们将使用 AES-256 算法。
// config.js
import dotenv from 'dotenv'
dotenv.config()
const { NODE_ENV, PORT, SECRET_KEY, SECRET_IV, ECNRYPTION_METHOD } = process.env
export default {
env: NODE_ENV,
port: PORT,
secret_key: SECRET_KEY,
secret_iv: SECRET_IV,
ecnryption_method: ECNRYPTION_METHOD,
}
注意:配置文件在 encryption.js 文件中导入,因此您需要确保配置文件与 encryption.js 文件位于同一目录中。
创建服务器文件
要创建服务器文件,请在项目根目录中创建一个名为 server.js 的新文件。
// server.js
import express from 'express'
const app = express()
app.use(express.json())
app.use(express.urlencoded({ extended: false }))
app.listen(3000, () => {
console.log('Server is running on port 3000')
})
这将创建一个新的 Express 服务器,并监听 3000 端口。
创建加密模块
要创建加密模块,请在项目根目录下创建一个名为 encryption.js 的新文件。
在该文件中,您需要导入 crypto 模块和配置文件。配置文件包含 secret_key、secret_iv 和 encryption_method。
然后将这些变量赋值给它们各自的变量。如果其中任何一个变量缺失,则会抛出错误。
然后使用加密算法生成一个用于加密的秘密哈希值。该哈希值使用 sha512 方法,并结合配置文件中的 secret_key 和 secret_iv 参数生成。最后,将哈希值缩短为密钥 32 个字符,初始化向量 16 个字符。
注:iv 代表初始化向量。初始化向量是一个随机值,用于加密明文的第一块。解密密文需要初始化向量,因此它必须与密文一起传输或存储。
然后导出两个函数:encryptData() 和 decryptData()。encryptData() 函数接收数据作为参数,并使用 crypto 函数中的 cipheriv 方法对其进行加密,先将其转换为十六进制格式,然后再转换为 base64 格式。decryptData() 函数接收加密后的数据作为参数,先将其转换为 utf8 格式,然后再使用 crypto 函数中的 decipheriv 方法对其进行解密,最后将其转换回 utf8 格式。
// encryption.js
import crypto from 'crypto'
import config from './config.js'
const { secret_key, secret_iv, ecnryption_method } = config
if (!secret_key || !secret_iv || !ecnryption_method) {
throw new Error('secretKey, secretIV, and ecnryptionMethod are required')
}
// Generate secret hash with crypto to use for encryption
const key = crypto
.createHash('sha512')
.update(secret_key)
.digest('hex')
.substring(0, 32)
const encryptionIV = crypto
.createHash('sha512')
.update(secret_iv)
.digest('hex')
.substring(0, 16)
// Encrypt data
export function encryptData(data) {
const cipher = crypto.createCipheriv(ecnryption_method, key, encryptionIV)
return Buffer.from(
cipher.update(data, 'utf8', 'hex') + cipher.final('hex')
).toString('base64') // Encrypts data and converts to hex and base64
}
// Decrypt data
export function decryptData(encryptedData) {
const buff = Buffer.from(encryptedData, 'base64')
const decipher = crypto.createDecipheriv(ecnryption_method, key, encryptionIV)
return (
decipher.update(buff.toString('utf8'), 'hex', 'utf8') +
decipher.final('utf8')
) // Decrypts data and converts to utf8
}
创建路由
要创建路由,请在项目根目录中创建一个名为 routes.js 的新文件。
在这个文件中,你需要导入 Express 路由和加密模块。加密模块包含 encryptData() 和 decryptData() 函数。
encryptData() 函数用于加密请求体中发送的数据,decryptData() 函数用于解密请求体中发送的数据。
// routes.js
import express from 'express'
import { encryptData, decryptData } from './encryption.js'
const router = express.Router()
router.post('/encrypt', (req, res) => {
const { data } = req.body
const encryptedData = encryptData(data)
res.json({ encryptedData })
})
router.post('/decrypt', (req, res) => {
const { encryptedData } = req.body
const data = decryptData(encryptedData)
res.json({ data })
})
export default router
创建 .env 文件
要创建 .env 文件,请在项目根目录中创建一个名为 .env 的新文件。
此文件中将存储 secret_key、secret_iv 和 encryption_method。secret_key 和 secret_iv 用于生成密钥哈希值,该哈希值用于加密和解密。encryption_method 用于指定要使用的加密算法。
在本教程中,我们将使用 AES-256 算法。
NODE_ENV=development
PORT=3000
SECRET_KEY=secretKey
SECRET_IV=secretIV
ECNRYPTION_METHOD=aes-256-cbc
注意:.env 文件在 config.js 文件中导入,用于存储 secret_key、secret_iv 和 encryption_method。
创建 .gitignore 文件
要创建 .gitignore 文件,请在项目根目录下创建一个名为 .gitignore 的新文件。在这个文件中,您将忽略 node_modules 文件夹和 .env 文件。
node_modules
.env
导入服务器文件中的路由
要将路由导入服务器文件,请在 server.js 文件中导入 routes 文件。更新后的 server.js 文件将如下所示:
// server.js
import express from 'express'
import routes from './routes.js'
const app = express()
app.use(express.json())
app.use(express.urlencoded({ extended: false }))
app.use(routes)
app.listen(3000, () => {
console.log('Server is running on port 3000')
})
测试 API
要测试 API,请在终端中运行以下命令启动服务器:
yarn dev
注意:开发脚本在 package.json 文件中定义。
要测试加密路由,请向http://localhost:3000/encrypt发送 POST 请求,并在请求正文中附上以下数据:
{
"data": "Hello World"
}
要测试解密路由,请向
http://localhost:3000/decrypt发送 POST 请求,并在请求正文中输入以下数据:
{
"data": "encryptedData"
}
结论
在本教程中,您学习了如何使用Node.js和Express创建一个用于加密和解密数据的API。您还学习了如何使用crypto模块来加密和解密数据。
您可以在GitHub代码库中找到本教程的源代码。
如有任何疑问,欢迎在下方评论区留言。
祝您编程愉快!