2017-04-03 35 views
1

我们使用节点模块加密和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,并尝试确定查询字符串是否正确解密。

回答

2

这里是我会做什么。如果您有要加密,并能告诉您正确解密它算账,而不是加密裸串像'abc'您可以加密像{string: 'abc'}对象的JSON表示的字符串 - 这将是一个字符串:'{"string":"abc"}'

可以编码字符串,像这样具有类似的功能:

let encode = string => JSON.stringify({string}); 

现在encode('abc')返回一个字符串:'{"string":"abc"}'

当解密字符串和JSON.parse()它和它导致我n一个具有string属性的对象,那么你可以相当肯定它不是随机垃圾。

解密,你可以将结果与这样的功能的解码之后:

let decode = json => { try { return JSON.parse(json).string; } catch (e) {} }; 

这将返回正确的字符串正确的JSON,但未定义无效JSON。

当然你也可以做这样的事情,在许多不同的方式,但是这是你就不需要那么多的改变你的代码相当简单的方式。

对于更健壮的解决方案可以使用JWT:

+0

JSON并不是真的需要,所需要的一切,以及完成的是添加一个必须正确解密的金丝雀。 – zaph

+0

@zaph是的,当然JSON是不需要的(这就是为什么我写“你可以用许多不同的方式做这样的事情”),但是JSON做这样的事情是相当简单的。它可能会与其他字符串一起加入字符串,并在解密后查看它是否存在。这里的JSON属性的键名称充当了金丝雀,但当然可以通过多种方式完成。 – rsp

+0

更简单的是预先(或附加)一个字符串,如:“Iamacanary”。最简单的解决方案通常是最好的,也更难以“搞砸”。 – zaph

0

确保正确的密钥的通常方法被使用和/或加密的数据已被修改的加密然后是MAC。这意味着使用加密密钥的派生来HMAC加密的数据并将HMAC结果附加到加密的数据。当解密加密数据(少于HMAC结果)再次通过带有派生密钥的HMAC运行时,并与附加的HMAC值进行比较。如果成功,则解密数据,否则密钥或数据不正确。

所有这可能是不可接受的额外开销。另一种方法是将数据加密之前和解密之后验证该值小的数据项目(a canary)添加。但是这对于一些攻击是不安全的。