我们使用Node模块Crypto和Express来提供一些查询字符串和表单名称混淆。
'use strict';
var algorithm = 'aes-256-ctr'
, crypto = require('crypto')
;
var enc = function(string, key){
var cipher = crypto.createCipher(algorithm, key);
var buff = Buffer.from(string, 'utf8');
return Buffer.concat([cipher.update(buff), cipher.final()]).toString('hex').toUpperCase();
};
var dec = function(string, key){
var decipher = crypto.createDecipher(algorithm, key);
var buff = Buffer.from(string, 'hex');
return Buffer.concat([decipher.update(buff), decipher.final()]).toString('utf8');
};
使用的密钥很可能是随机会话GUID,因此只要该会话有效,查询字符串就会有效。
问题我看到,如果会话GUID与编码字符串的内容不同,该函数仍将解密十六进制字符串,但结果将无效。
是否有正则表达式字符串(用于检测字符串中是否返回了任何非有效字符)或其他一些方法来确定是否使用了其他键来解码除原始键以外的字符串?
我将很快创建一个快速中间件,它将查看每个传入的req并确定req.query或req.form是否需要被解密,并尝试确定查询字符串是否被正确解密。
答案 0 :(得分:2)
这是我要做的。如果您有一个要加密的字符串,并且能够告诉您之后已正确解密它,而不是像'abc'
那样加密一个简单的字符串,那么您可以加密像{string: 'abc'}
之类的对象的JSON表示。 - 这将是一个字符串:'{"string":"abc"}'
您可以使用以下函数对此类字符串进行编码:
let encode = string => JSON.stringify({string});
现在encode('abc')
会返回一个字符串:'{"string":"abc"}'
当你解密一个字符串并JSON.parse()
它并导致一个具有string
属性的对象时,你可以相当确定它不是随机垃圾。
解密后,您可以使用以下函数解码结果:
let decode = json => { try { return JSON.parse(json).string; } catch (e) {} };
将为正确的JSON返回正确的字符串,但未定义无效的JSON。
当然,您可以通过多种不同的方式执行此类操作,但这是一种非常简单的方法,您不需要更改代码。
对于更强大的解决方案,您可以使用JWT:
答案 1 :(得分:0)
正在使用确保正确密钥和/或已修改加密数据的常用方法是加密MAC。这意味着使用加密密钥的推导来对HMAC加密数据并将HMAC结果附加到加密数据。当解密加密数据(少于HMAC结果)时,再次使用派生密钥通过HMAC运行,并与附加的HMAC值进行比较。如果成功则解密数据,否则密钥或数据不正确。
所有这些都可能是不可接受的开销。另一种方法是在加密之前和解密后验证值,在数据中添加一个小数据项(canary)。但这对某些攻击并不安全。