问题:我们必须加密特定表格上的某个列(Postgres)。它必须在我们的nodejs / sequelize应用程序层中的SQL查询和中可解密。加密可以在任一层中进行,但必须可以从任何一个解码。
我遇到的问题(我确定它的用户错误)是,如果我在数据库中加密,我只能在数据库中解密,而节点也是如此。
我尝试在postgres中使用PGP_SYM_ENCRYPT
和ENCRYPT
,在节点中尝试使用crypto
和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)
加密很好,在尝试解密时(使用PGP_SYM_DECRYPT
或DECRYPT
)解密罚款但Postgres错误。将结果字段转换为::TEXT
并将其粘贴到在线AES Decrypter中会返回预期值。
我真的想要避免在我们的节点存储库/查询中添加一堆样板文件,我觉得这应该可行。使用相同的加密算法应该产生相同的结果
非常感谢任何微调或指针
答案 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原始功能未记录的事物的列表:
aes-192-cbc
进行加密如果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
方法,以及翻转杂耍的十六进制/文本之间似乎正在发挥作用。