Postgres和Node

时间:2018-05-22 20:02:20

标签: node.js postgresql encryption aes

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

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

我尝试在postgres中使用PGP_SYM_ENCRYPTENCRYPT,在节点中尝试使用cryptocrypto-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)

加密很好,在尝试解密时(使用PGP_SYM_DECRYPTDECRYPT)解密罚款但Postgres错误。将结果字段转换为::TEXT并将其粘贴到在线AES Decrypter中会返回预期值。

真的想要避免在我们的节点存储库/查询中添加一堆样板文件,我觉得这应该可行。使用相同的加密算法应该产生相同的结果

非常感谢任何微调或指针

2 个答案:

答案 0 :(得分:1)

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原始功能未记录的事物的列表:

  • 密钥将自动填充以匹配以下三种长度之一:128位,192位,256位
  • 当密钥长度超过限制时,
  • 算法将自动升级。例如如果密钥超过128位,将使用aes-192-cbc进行加密
  • 如果密钥超过256位,它将被截断为256位。

如果Postgres拥有这些功能的适当文档,则使用应用程序语言(Java脚本或Java)复制它会更加容易。

答案 1 :(得分:0)

好的,我得到了它,希望正确

我做的是:

加密节点中的crypto.createCipheriv('aes-256-cbc', new Buffer(config.AES_KEY), iv),pgsql中的encrypt_iv并在数据库中存储为hex,并使用crypto.createDecipheriv / decrypt_iv解密为{{1} }} / text

我不知道我错过了哪一部分,但是在指定utf8之间,使用aes256方法,以及翻转杂耍的十六进制/文本之间似乎正在发挥作用。