mysql - Nodejs Crypto加密字符串存储在MySQL中后无法正确解密
问题描述
我有一个简单的 nodejs 应用程序,它存储来自外部服务的令牌,在数据库受损的情况下将它们存储为纯字符串是不安全的,所以我需要对它们进行加密。
将以下 github 要点复制并粘贴到我的应用程序simple-nodejs-iv-encrypt-decrypt.js
我能够成功加密和解密我的字符串,但是一旦将加密的字符串保存到MySQL
它就不再解密为匹配的字符串
我的 MySQL 列已格式化encryptedToken VARCHAR(255)
// before storing to database
{
encryptedToken: 'OKWLlYEsCtddWQOL8ezQBI+whtU30gVs67nGiRLxxca10Y4AELjMZN3afVzuys17leE9U9Ski+fByaEXFTXnefDUdyR4PUwJBi6poY1RHOY=',
decryptedToken: 'Z4XkR0vkrbAO6LzmaYGYa0dnaaxvlkIme27L-GlPB7l6M4gkikz1S_vTfJyCUJMx'
}
// after storing to database
{
encryptedToken: 'OKWLlYEsCtddWQOL8ezQBI+whtU30gVs67nGiRLxxca10Y4AELjMZN3afVzuys17leE9U9Ski+fByaEXFTXnefDUdyR4PUwJBi6poY1RHOY=',
decryptedToken: ':D�\b�O3Qlס��,,\u0017aYGYa0dnaaxvlkIme27L-GlPB7l6M4gkikz1S_vTfJyCUJMx'
}
使用的算法是aes256
,编码是base64
解决方案
我相信这是因为您每次都使用不同的 IV(初始化向量)。
每次调用时,encryptionHelper 函数 getKeyAndIV 都会创建一个随机 IV,因此解密将不是确定性的。
如果您确保每次都使用相同的 IV,则解密的令牌也应该相同。
我已经这样测试了:
SQL
create table tokens (encryptedToken varchar(255))
Javascript/Node.js
const encryptionHelper = require("./simple-nodejs-iv-encrypt-decrypt.js")
// This could be anything
const token = "abcdefghijklmonp";
// We're using fixed values here. In reality you could use a different IV for each row, it's ok to store this in the database.
const key = Buffer.from("MTIzNDU2Nzg5MGFiY2RlZmdoaWprbG1ub3BxcnN0dXY=", "base64");
const iv = Buffer.from("26vFZGhH66xFszo59pEaWA==", "base64");
const encryptedToken = encryptionHelper.encryptText(encryptionHelper.CIPHERS.AES_256, key, iv, token, "base64");
// con should be initialized with a connection to the relevant db.
con.query("insert into tokens (encryptedToken) values (?)", [encryptedToken ], (error, results) => {
if (error) {
console.error("Insert query failed: ", error);
} else {
console.log("Token insert successful!");
}
});
con.query("select * from tokens", (error, results) => {
if (error) {
console.error("Select query failed: ", error);
return;
}
console.log("Tokens (encrypted):", results.map(r => r.encryptedToken));
console.log("Tokens (decrypted):", results.map(r => encryptionHelper.decryptText(encryptionHelper.CIPHERS.AES_256, key, iv, r.encryptedToken, "base64").toString("base64")));
});
// Let's just ensure con is closed
setTimeout(() => {
con.end()
}, 100);
推荐阅读
- angular - 单元测试用例检查函数是否被调用
- html - Vue:SCSS 样式未应用于服务,但仅在重新加载时应用
- python - 500:Jupyter Notebok 中的内部服务器错误
- javascript - 存储在 aws polly 上提取的音频,将其存储在 S3 上并将其上传到 Javascript 中的 html 元素上
- java - 在不重新编译的情况下更新损坏的依赖 module-info.java?
- python - Python 正则表达式选择所有不匹配模式的元素
- regex - 替换为正则表达式时,如何将数字附加到匹配组的末尾?
- reactjs - 代码空间 (online.visualstudio.com) - 找不到模块 'tslint/lib/tsLintCli.js'
- jquery - 如何在jquery中单击iFrame时更改动态添加的iframe的背景颜色
- vb.net - 为什么我的 Visual Studio 不显示任何文本?