2017-08-12 71 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

非常感谢您的耐心 - 我觉得我很接近,但我不了解基本原理 - 您是一位救生员。 –

相关问题