2016-03-02 64 views
1
解密

我想在CBC模式(庫的默認值)使用phpseclib AES加密字符串AES:加密使用phpseclib與CryptoJS

$cipher = new Crypt_AES(); 
$cipher->setKey('abcdefghijklmnop'); 
$cipher->setIV(crypt_random_string($cipher->getBlockLength() >> 3)); 
$cipher->encrypt("hello world") 

然後,我需要解密使用CryptoJS或類似的NodeJS ..我已經嘗試了不同的庫,但到目前爲止沒有運氣。我猜這個問題與編碼輸出有關,與每個庫不同。

有沒有人有如何實現這種互操作性方案的工作示例?

可以使用其他庫如Crypto。 一個例子Base64編碼輸出爲MF9lCR4DaW1R0adIe03VEw==

這樣的想法是解密如下:

var helloWorld = CryptoJS.AES.decrypt("MF9lCR4DaW1R0adIe03VEw==", key).toString(); 
+0

爲什麼你使用節點第三方密碼庫時,有一個內置的更快? – mscdex

+0

你可以舉例加密輸出(例如十六進制或base64)嗎? – mscdex

+0

@mscdex只是根據你的要求更新了一些例子的問題。順便說一下,節點的加密庫也是一個選項.. – Roberto14

回答

2

您需要解密時以前生成IV。它不一定是保密的,但必須是不可預知的(這是你的情況)。您可以將它與密文一起發送。一種常用的方法是將其預先加密到密文中,並在解密過程中將其切斷。

CryptoJS支持兩種類型的加密。如果將密鑰作爲字符串傳遞,它將使用OpenSSL的密鑰派生函數來派生一個帶有鹽的新密鑰。你不需要這個,因爲你使用了明確的密鑰。爲此,您需要將密鑰傳遞爲WordArray(CryptoJS的本機二進制數據結構)。此外,密文有望成爲一個既OpenSSL的格式化字符串或CipherParams對象:

var message = CryptoJS.AES.decrypt({ 
    ciphertext: CryptoJS.enc.Base64.parse("MF9lCR4DaW1R0adIe03VEw==") 
}, CryptoJS.enc.Utf8.parse('abcdefghijklmnop'), { 
    iv: iv // retrieve the IV somehow 
}).toString(CryptoJS.enc.Utf8); 
+0

我以爲IV已經附加到加密數據(密文),並且會在節點上無縫分析..所以我沒有嘗試手動設置它。謝謝你的迴應! – Roberto14

+1

您可以通過查看密文的長度來檢查這一點。 Base64的爆炸率爲4/3。這意味着實際的密文長度爲'len(b64)* 3/4-paddingChars',這在你的情況下是'24 * 3/4-2 = 18-2 = 16'。 16是AES的塊大小,並且由於CBC是非流模式,它必須至少產生一個塊。所以IV是沒有地方的。 –