mysql 和 node.js 上的 AES 加密

AES encryption on mysql and node.js

我在问题下面挣扎了好几天,之前发布了同样的问题,但没有得到任何正面反馈。

我在构建 aes_encrypt 方法中使用 mysql 来 加密新数据和现有数据 https://dev.mysql.com/doc/refman/8.0/en/encryption-functions.html

SET @@SESSION.block_encryption_mode = 'aes-256-ecb';
INSERT INTO test_aes_ecb ( column_one, column_two )
values ( aes_encrypt('text','key'), aes_encrypt('text', 'key'));

我用的是ecb ciper,所以没必要用iv。问题是我无法从node.js方面解密

我正在使用 sequelize 并尝试通过 model --> decrypt 从节点端调用数据。

我尝试使用以下库,

"aes-ecb": "^1.3.15",
"aes256": "^1.1.0",
"crypto-js": "^4.1.1",
"mysql-aes": "0.0.1",

下面是来自 sequelize 调用

的代码片段
async function testmysqlAESModel () {
    const users = await test.findAll();
    console.log('users', users[0].column_one);
    var decrypt = AES.decrypt( users[0].column_one, 'key' );
}

它返回 缓冲区 数据并且无法从节点端解密,有人可以为此提供适当的示例吗?我挣扎了几天。

编辑

已将记录插入 mysql,如下查询。

SET @@SESSION.block_encryption_mode = 'aes-256-ecb';
INSERT INTO test_aes_ecb ( id, column_one, column_two )
VALUES (1, 2,AES_ENCRYPT('test',UNHEX('gVkYp3s6v9y$B&E)H@McQeThWmZq4t7w')));

在这样调用的nodejs中,

testmysqlAESModel();
async function testmysqlAESModel () {
    const users = await test.findAll();
    console.log('users', users[0].column_one);
    var decipher = crypto.createDecipheriv(algorithm, Buffer.from("gVkYp3s6v9y$B&E)H@McQeThWmZq4t7w", "hex"), "");
    var encrypted = Buffer.from(users[0].column_one); // Note that this is what is stored inside your database, so that corresponds to users[0].column_one
    var decrypted = decipher.update(encrypted, 'binary', 'utf8');
    decrypted += decipher.final('utf8');
    console.log(decrypted);

}

我遇到错误,

我在下面使用 link 创建了 256 位密钥。

https://www.allkeysgenerator.com/Random/Security-Encryption-Key-Generator.aspx

仍然无法修复,您能否提供示例项目或任何类型的支持代码片段?

这里有多个问题:

  1. 确保您的密钥长度正确。 AES 指定了特定的密钥长度(即 128、196 和 256 位)。如果您使用任何其他密钥长度,那么您的密钥将被加密库填充(零扩展)或截断。这是一个非标准过程,不同的实现会以不同的方式执行此操作。为避免这种情况,请使用正确长度的密钥并将其存储为十六进制而不是 ascii(以避免字符集问题)

  2. 关于密码到密钥推断的潜在问题。一些 AES 实现使用方法从 passwords/passphrases 推断密钥。由于您在 MySQL 中使用原始密钥,因此您不想推断任何内容,但也想在 NodeJS 中使用原始密钥。这意味着,如果您使用的是本机加密模块,则要使用 createDecipheriv 而不是 createDecipher

注意:您使用的 AES 模式 (ECB) 本质上是不安全的,因为相同的输入会导致相同的输出。有一些方法可以使用其他 AES 模式,例如 CBC 或 GCM。您已收到警告。

示例:

MySQL SELECT AES_ENCRYPT('text',UNHEX('F3229A0B371ED2D9441B830D21A390C3')) as test; returns 缓冲区 [145,108,16,83,247,49,165,147,71,115,72,63,152,29,218,246];

在 Node 中对此进行解码可能如下所示:

var crypto = require('crypto');
var algorithm = 'aes-128-ecb';
var decipher = crypto.createDecipheriv(algorithm, Buffer.from("F3229A0B371ED2D9441B830D21A390C3", "hex"), "");
var encrypted = Buffer.from([145,108,16,83,247,49,165,147,71,115,72,63,152,29,218,246]); // Note that this is what is stored inside your database, so that corresponds to users[0].column_one
var decrypted = decipher.update(encrypted, 'binary', 'utf8');
decrypted += decipher.final('utf8');
console.log(decrypted);

这会再次打印 text

请注意,F3229A0B371ED2D9441B830D21A390C3 是本例中的关键,您显然必须创建自己的。只需确保您的密钥与示例的长度相同,并且是有效的十六进制字符串。