2017-04-03 86 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)添加。但是這對於一些攻擊是不安全的。