Postgres 和 Node 之间的加密/解密

2023-12-22

Problem:我们必须加密某个表(Postgres)上的某个列。它必须可以在 SQL 查询中解密and在我们的nodejs/sequelize应用程序层中。加密可以发生在任一层,但必须可以从任一层进行解码。

我遇到的问题(我确信这是用户错误)是,如果我在数据库中加密,我只能在数据库中解密,对于节点也是如此。

我尝试过使用PGP_SYM_ENCRYPT and ENCRYPT在 postgres 和crypto and crypto-js/aes在节点中。我已经得到它的解密没有错误,但返回乱码。

到目前为止我尝试过的一些事情(测试键是thirtytwocharsthirtytwocharsplus):

set() {
  this.setDataValue('field', seq.cast(seq.fn('PGP_SYM_ENCRYPT', val, 
  config.AES_KEY), 'text'))
}

这正确地写入了字段,以便 PGP_SYM_DECRYPT 将解密它,但是(显然?)没有办法告诉 Sequelize 用函数调用包装字段名称,所以我觉得有很多额外的 js 是可以避免的

const decipher = crypto.createDecipher('aes256', config.AES_KEY)
decipher.setAutoPadding(false);
return decipher.update(new Buffer(this.getDataValue('field', 'binary'), 'binary', 'ascii')) + decipher.final('ascii')

这将解码该字段但返回乱码(�Mq��8Ya�b) 而不是值 (test)

aes.encrypt('test', config.AES_KEY)
aes.decrypt(field, config.AES_KEY).toString(CryptoJS.enc.Utf8)

这可以很好地加密,解密也很好,但是在尝试解密时会出现 Postgres 错误(使用PGP_SYM_DECRYPT or DECRYPT)。将结果字段投射到::TEXT并将其粘贴到在线 AES 解密器中会返回预期值。

I really希望避免向我们的节点存储库/查询添加一堆样板,我真的觉得这应该可行。使用相同的加密算法应该产生相同的结果

任何轻推或指示将不胜感激


Postgres 关于原始加密函数的文档相当不清楚。经过几次尝试和失败,我成功地在nodejs中复制了大部分逻辑。

这是我使用的程序。

const crypto = require('crypto');

const iv = Buffer.alloc(16); // zeroed-out iv

function encrypt(plainText, algorithm, key) {
  const cipher = crypto.createCipheriv(algorithm, key, iv);
  let encrypted = cipher.update(plainText, 'utf8', 'base64');
  encrypted += cipher.final('base64');
  return encrypted;
}

function decrypt(encrypted, algorithm, key) {
  const decrypt = crypto.createDecipheriv(algorithm, key, iv);
  let text = decrypt.update(encrypted, 'base64', 'utf8');
  text += decrypt.final('utf8')
  return text;
}

const originalText = "hello world";
const userKey = 'abcd'
const algorithm = 'aes-128-cbc';

const paddedKey = Buffer.concat([Buffer.from(userKey), Buffer.alloc(12)]); // make it 128 bits key

const hw = encrypt(originalText, algorithm, paddedKey);
console.log("original", originalText);
console.log("encrypted:", hw);
console.log("decoded: ", decrypt(hw, algorithm, paddedKey).toString());

这里还列出了未记录的 postgres 原始函数的内容:

  • 密钥将自动填充以匹配 3 个长度之一:128 位、192 位、256 位
  • 当密钥长度超过限制时,算法自动升级。例如如果密钥超过128位,aes-192-cbc将用于加密
  • 如果密钥超过 256 位,则会被截断为 256 位。

如果 Postgres 有这些函数的正确文档,那么用应用程序语言(Javascript 或 Java)复制它会更容易。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Postgres 和 Node 之间的加密/解密 的相关文章

随机推荐