2017-08-12 68 views
0

我正在使用CryptoJS手動解密具有提供的一組值的字符串。祕密提供,然後SHA256已被採取。消息和初始化向量以64進制編碼。這是我正在嘗試的,但每次運行它時,輸出都會發生變化 - 這怎麼可能?!我在我無計可施......CryptoJS解密每次都會更改

// Key and take the hash of it 
var secretKey = 'TESTING123Secret_Key'; 
var secretKeyHash = CryptoJS.SHA256(secretKey).toString(CryptoJS.enc.Hex); 

// Base 64 encoded values 
var accountNumberBase64 = 'nxjYfo4Stw63YBEcnjo3oQ=='; 
var initializationVectorBase64 = 'HnNcvu9AP9yl09APWkWnDQ=='; 

// decode the values provided above 
var accountNumberEncrypt = atob(accountNumberBase64); 
var initializationVector = atob(initializationVectorBase64); 

// Use crypto to decrypt 
var decrypted = CryptoJS.AES.decrypt(
    { 
     ciphertext: accountNumberEncrypt, 
     salt: '' 
    }, 
    secretKeyHash, 
    { 
     mode: CryptoJS.mode.CBC, 
     padding: CryptoJS.pad.NoPadding, 
     iv: initializationVector, 
     salt: '' 
    } 
); 
console.log(' decrypted, by hand: ' + decrypted.toString(CryptoJS.enc.Hex)); 

最後一行每到這個運行時間(在頁面加載運行)的變化 - 相同的值提供每一次,輸出是不同的。

如何它應該工作:

Decryption Instructions: 
1. A static, secret key will be shared which will be used for decryption (Secret Key TBD). 
    a. HASH the secret key with SHA256, encode it to Hex and use the first 32 characters. This will be used as the KEY when decrypting. 
2. Two pieces of information will be sent via the POST method 
    a. Parameter 「AN」: A Base64 Encoded, AES-256-CBC Encrypted string which will represent the Account Number when decrypted 
    b. Parameter 「IV」: A Base64 Encoded initialization vector (IV) string which will be used in decrypting the Account Number string 
3. Base64 Decode both parameters 
4. Using the AES-256-CBC method, decrypt the encrypted string (which was base64 decoded as part of Step #3) with the initialization vector decoded in Step #3 and the hash created in Step #1a 
5. The decryption should then provide you the account number. 

Java code

+1

有一些問題,你的代碼,如傳遞密鑰字符串,而不是使用'WordArray':'VAR secretKeyHash = CryptoJS.SHA256(祕密密鑰) ;',但那個和其他問題不會產生任何明智的解密(至少對我來說):6497b502a3b2558263d2a9cd599d6bbe。你能顯示產生IV和密文的代碼嗎? –

+1

你不應該使用簡單的散列函數來保護你的用戶密碼。你需要使用像PBKDF2,bcrypt,scrypt和Argon2這樣強大的散列方案。一定要使用高成本因子/迭代次數。選擇成本是很常見的,因此一次迭代至少需要100ms。查看更多:[如何安全地哈希密碼?](https://security.stackexchange.com/q/211/45523) –

+0

@ArtjomB。感謝評論,這是一個朋友請求一些工作幫助,我不知道實際加密的具體情況。我已經更新了他們被告知解密應該是什麼,這是所有提供的,以及他們在Java中說的工作在這裏https://pastebin.com/kdy0NcnK –

回答

1

有你的代碼中的許多問題。很難說什麼是非確定性解密的真正責任。我想這是事實,你將密鑰作爲字符串傳遞,這意味着CryptoJS會認爲它是一個密碼,並嘗試使用EVP_BytesToKey從中派生出一個密鑰。由於鹽沒有設置,CryptoJS可能會產生一個錯誤,它會產生一個隨機鹽來解密(它不應該)。如果您想手動提供密鑰,則需要將密鑰解析爲WordArray

另一個主要問題是使用非CryptoJS方法進行解碼(atob),這意味着您會得到一些CryptoJS無法直接讀取的數據格式。 CryptoJS依靠內部WordArray來表示所有二進制數據,或者期望所有字符串都是UTF-8編碼的。

工作代碼:

// Key and take the hash of it 
 
var secretKey = 'TESTING123Secret_Key'; 
 
var secretKeyHash = CryptoJS.SHA256(secretKey).toString(CryptoJS.enc.Hex).slice(0,32); 
 
secretKeyHash = CryptoJS.enc.Utf8.parse(secretKeyHash); 
 

 
// Base 64 encoded values 
 
var accountNumberBase64 = 'nxjYfo4Stw63YBEcnjo3oQ=='; 
 
var initializationVectorBase64 = 'HnNcvu9AP9yl09APWkWnDQ=='; 
 

 
var ct = CryptoJS.enc.Base64.parse(accountNumberBase64); 
 
var iv = CryptoJS.enc.Base64.parse(initializationVectorBase64); 
 

 
// Use crypto to decrypt 
 
var decrypted = CryptoJS.AES.decrypt({ 
 
    ciphertext: ct 
 
    }, 
 
    secretKeyHash, { 
 
    mode: CryptoJS.mode.CBC, 
 
    padding: CryptoJS.pad.NoPadding, 
 
    iv: iv 
 
    } 
 
); 
 
console.log(' decrypted, by hand: ' + decrypted.toString(CryptoJS.enc.Utf8));
<script src="https://cdn.rawgit.com/CryptoStore/crypto-js/3.1.2/build/rollups/aes.js"></script> 
 
<script src="https://cdn.rawgit.com/CryptoStore/crypto-js/3.1.2/build/rollups/sha256.js"></script> 
 
<script src="https://cdn.rawgit.com/CryptoStore/crypto-js/3.1.2/build/components/pad-nopadding-min.js"></script>

+0

非常感謝您的耐心 - 我覺得我很接近,但我不瞭解基本原理 - 您是一位救生員。 –

相關問題