2013-01-14 77 views
3

我試圖從閃存(客戶端)的JavaScript發送加密數據(如運行在ASP的JScript)在服務器端。如何使用AES解密ECB加密JS

有幾個JavaScript的AES庫,但他們幾乎沒有證件。我正在嘗試加密-js,但不能讓代碼工作。下面的例子生成一個空輸出,它應該生成「6bc1bee22e409f96e93d7e117393172a」。

<html xmlns="http://www.w3.org/1999/xhtml"> 
<head> 
</head> 
<body> 
<script src="http://crypto-js.googlecode.com/svn/tags/3.1/build/rollups/aes.js"></script> 
<script src="http://crypto-js.googlecode.com/svn/tags/3.1/build/components/mode-ecb.js"></script> 
<script src="http://crypto-js.googlecode.com/svn/tags/3.1/build/components/pad-nopadding.js"></script> 
<script> 
    var key = CryptoJS.enc.Hex.parse('2b7e151628aed2a6abf7158809cf4f3c'); 
    var data = CryptoJS.enc.Hex.parse('3ad77bb40d7a3660a89ecaf32466ef97'); 
    var decrypted3 = CryptoJS.AES.decrypt(data, key, {mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.NoPadding }); 
    document.write("<br /> dec3: " + decrypted3.toString()); 
</script> 
</body> 
</html> 

我參加了一個記錄工作密鑰和加密的數據從http://www.inconteam.com/software-development/41-encryption/55-aes-test-vectors

我使用歐洲央行,因爲它不需要靜脈輸液或鹽的唯一版本,因爲服務器不會知道IV或鹽在客戶端使用,所以無法解密數據。

沒有人有任何線索,爲什麼上面的失敗,對數據進行解密,或者知道任何文檔?

更新:經過幾個小時的反覆試驗,我想出了一個產生輸出的組合:7c121d95a84573b6120ada2ffff1ce3118561eba40555c0b但是,這仍然是不正確的。產生這種變化是:

var decrypted3 = CryptoJS.AES.decrypt('3ad77bb40d7a3660a89ecaf32466ef97', key, {mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.NoPadding }); 

即,我以十六進制字符串的形式傳遞了數據,該數據不是正確的,但至少會產生輸出。

下一個問題將是填充的問題。在客戶端上,我使用AS3 hurlant庫,它只提供兩種填充策略:NONE和PKCS#5。在crypto-js中,可用的策略是:

Pkcs7 (the default) 
Iso97971 
AnsiX923 
Iso10126 
ZeroPadding 
NoPadding 

這是否意味着在兩個庫之間不會有每次解密數據的機會?在我必須編寫自己的填充黑客(在AS3和java之間)之前,要添加或刪除尾隨數據,但是這需要花費數天的時間對二進制數據進行反覆試驗 - 必須有更簡單的方法從客戶端發送單個加密字符串到服務器。

SSL不是一個選項作爲客戶端,用戶可以簡單地使用查爾斯代理或類似的看,並與未加密的數據篡改。

+0

我正在嘗試同樣的事情,它似乎沒有工作。我用ECB使用Crypto.JS進行加密,然後嘗試使用CryptoJS和ECB進行解密,CryptoJS生成的是相同的哈希,但它不起作用。我設法得到了一個輸出,但這是錯誤的。我覺得有些東西不適合圖書館。唯一可行的是給加密到解密器的CryptoJS返回的整個對象。這很愚蠢,因爲我想把它發送給其他人解密。 –

+0

不要使用ECB模式,它不安全,請參閱[ECB模式](https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Electronic_Codebook_.28ECB.29),向下滾動到企鵝。 取而代之的是將CBC模式與隨機IV一起使用,只是將加密數據與IV一起用於解密。 – zaph

回答

4

與歐洲央行一起,嘗試了與CBC的各種排列,並得到一個工作。似乎也可以將IV以明文形式從客戶端發送到服務器。

這裏是一個正確輸出「6bc1bee22e409f96e93d7e117393172a」的版本。休克。

<html xmlns="http://www.w3.org/1999/xhtml"> 
<head> 
</head> 
<body> 
<script src="http://crypto-js.googlecode.com/svn/tags/3.1/build/rollups/aes.js"></script> 
<!--script src="http://crypto-js.googlecode.com/svn/tags/3.1/build/components/mode-cbc.js"></script--> 
<script src="http://crypto-js.googlecode.com/svn/tags/3.1/build/components/pad-nopadding.js"></script> 
<script> 
    var key = CryptoJS.enc.Hex.parse('2b7e151628aed2a6abf7158809cf4f3c'); 
    var iv = CryptoJS.enc.Hex.parse('000102030405060708090A0B0C0D0E0F'); 
    var data = CryptoJS.enc.Hex.parse('7649abac8119b246cee98e9b12e9197d');  

    var encrypted = {}; 
    encrypted.key=key; 
    encrypted.iv=iv; 
    encrypted.ciphertext = data; 

    var decrypted = CryptoJS.AES.decrypt(encrypted, key, { iv: iv, padding: CryptoJS.pad.NoPadding }); 

    document.write("<br /> dec3: " + CryptoJS.enc.Hex.stringify(decrypted)); 
</script> 
</body> 
</html> 
+0

這個答案對我來說非常合適。如果您想將解密的字節視爲字符串,請使用: document.write(「
解密的文本:」+ decrypted.toString(CryptoJS.enc.Utf8)); –

+0

你可以顯示加密數據的js代碼嗎?我也在努力解密,不能讓你的代碼工作。也許看加密的數據可以幫助我。 – ian

7

下面的示例使用AES和ECB返回所需的輸出。

<html xmlns="http://www.w3.org/1999/xhtml"> 
<head> 
</head> 
<body> 
    <script src="http://crypto-js.googlecode.com/svn/tags/3.1/build/rollups/aes.js"></script> 
    <script src="http://crypto-js.googlecode.com/svn/tags/3.1/build/components/mode-ecb.js"></script> 
    <script src="http://crypto-js.googlecode.com/svn/tags/3.1/build/components/pad-nopadding.js"></script> 


    <script> 
     var encrypted = '3ad77bb40d7a3660a89ecaf32466ef97', 
      key = CryptoJS.enc.Hex.parse('2b7e151628aed2a6abf7158809cf4f3c'), 
      cipherParams = CryptoJS.lib.CipherParams.create({ 
       ciphertext: CryptoJS.enc.Hex.parse(encrypted)   
      }); 

     var decrypted3 = CryptoJS.AES.decrypt(cipherParams, key, {mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.NoPadding }); 
     document.write("<br /> dec3: " + CryptoJS.enc.Hex.stringify(decrypted3)); 
    </script> 
</body> 
</html> 

唯一真正的差異是()創建一個對象cypherParams使用CryptoJS.lib.CipherParams.create。據官方docs cypherParams對象「讓你訪問加密過程中使用的所有參數」,包括密鑰,iv,salt和原始cypherText。基本上所有需要解密的信息。在我們的例子中,我們需要只用cypherText屬性將加密數據轉換爲cypherParam。順便說一下,cypherParam可以使用標準格式進行串化,這就是它如何傳遞給其他系統。

關於填充,因爲我understand它PKCS7是PKCS5的擴展,應該對任何暗號工作中使用PKCS5創建。當我嘗試上面的代碼示例沒有NoPadding選項時(默認爲Pkcs7),它不起作用,但我無法分辨創建加密數據時使用的是什麼。至少您鏈接到的AES測試向量頁面沒有告訴我們。

0

這是一個工作和更新的答案,帶有更新的CDN鏈接和一個將結果解密後的數據轉換爲純文本的函數。

<html xmlns="http://www.w3.org/1999/xhtml"> 
    <head> 
    </head> 
    <body> 
    <script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/components/core.js"></script> 

    <script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/components/cipher-core.js"></script> 

    <script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/components/aes.js"></script> 
    <script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/components/mode-ecb.js"></script> 
    <script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/components/pad-nopadding.js"></script> 


    <script> 
    var encrypted = 'B655564D4428C56E7F9E44D81770CFDBC3FB0FCEA8FFDF7CC936FFE6C7A595A0FE085FAA65796C4C24D0862FAF56CAA1880DCD281A891DD1E999F953F2B669291B41B486E0FEC5E11BE7B7348703665081E4FF79F815C35803506468548F3C5EE13B5783A0E22D91E08CB1897E4D135DA8C4E650A1D51FFDDD210311A0835FD8E8EE08CC968F8A0B0EF811554872A093', 
    key = CryptoJS.enc.Hex.parse('844AF9144552AFAE26A9C45FD5882718'), 
    cipherParams = CryptoJS.lib.CipherParams.create({ 
     ciphertext: CryptoJS.enc.Hex.parse(encrypted) 
    }); 

    var decrypted3 = CryptoJS.AES.decrypt(cipherParams, key, 
    {mode: CryptoJS.mode.ECB, 
     padding: CryptoJS.pad.NoPadding }); 
     document.write("<br />" + hex2a(CryptoJS.enc.Hex.stringify(decrypted3))); 
    function hex2a(hexx) { 
    var hex = hexx.toString();//force conversion 
    var str = ''; 
    for (var i = 0; i < hex.length; i += 2) 
     str += String.fromCharCode(parseInt(hex.substr(i, 2), 16)); 
    return str; 
} 
</script> 
</body> 
</html>