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
仍然无法修复,您能否提供示例项目或任何类型的支持代码片段?
这里有多个问题:
确保您的密钥长度正确。 AES 指定了特定的密钥长度(即 128、196 和 256 位)。如果您使用任何其他密钥长度,那么您的密钥将被加密库填充(零扩展)或截断。这是一个非标准过程,不同的实现会以不同的方式执行此操作。为避免这种情况,请使用正确长度的密钥并将其存储为十六进制而不是 ascii(以避免字符集问题)
关于密码到密钥推断的潜在问题。一些 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
是本例中的关键,您显然必须创建自己的。只需确保您的密钥与示例的长度相同,并且是有效的十六进制字符串。
我在问题下面挣扎了好几天,之前发布了同样的问题,但没有得到任何正面反馈。
我在构建 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
仍然无法修复,您能否提供示例项目或任何类型的支持代码片段?
这里有多个问题:
确保您的密钥长度正确。 AES 指定了特定的密钥长度(即 128、196 和 256 位)。如果您使用任何其他密钥长度,那么您的密钥将被加密库填充(零扩展)或截断。这是一个非标准过程,不同的实现会以不同的方式执行此操作。为避免这种情况,请使用正确长度的密钥并将其存储为十六进制而不是 ascii(以避免字符集问题)
关于密码到密钥推断的潜在问题。一些 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
是本例中的关键,您显然必须创建自己的。只需确保您的密钥与示例的长度相同,并且是有效的十六进制字符串。