我正在寻找一种方法,在CryptoJS中加密密码,然后在php中解密。我已经看了其他关于同一主题的帖子,但我需要有人来解释所有的IV和关键的东西。
我的CryptoJS加密代码:
password = document.getElementById("usrp").value;
password = CryptoJS.AES.encrypt(password, <?php echo '"'.$_SESSION['adk'].'"'; ?>);
IV
您正在使用需要IV的CBC操作模式。如果您对所有密文使用静态IV,那么您将错过加密的重要属性,即语义安全。如果您使用相同的IV,攻击者可能会观察您的密文,并确定您是否使用相同的密钥发送了相同的明文,因为密文将是相同的。
为了防止这种情况,您可以为每次加密生成一个随机IV。静脉注射不一定要保密,但必须是不可预测的。由于它不必是秘密的,您可以简单地将其附加到密文中,并在解密之前将其切掉,或者以结构化的方式发送它。你需要在解密过程中使用静脉注射。否则,第一个块将不同于原始明文。
请记住,CryptoJS的WordArray.random()
在内部使用Math.random()
,这不是加密安全的。最好使用更好的随机源。你可以使用这个drop in replacement从我的项目,该功能的半现代浏览器使用WebCrypto API:
(function(C){
var WordArray = C.lib.WordArray;
var crypto = window.crypto;
var TypedArray = Int32Array;
if (TypedArray && crypto && crypto.getRandomValues) {
WordArray.random = function(nBytes){
var array = new TypedArray(Math.ceil(nBytes / 4));
crypto.getRandomValues(array);
return new WordArray.init(
[].map.call(array, function(word){
return word
}),
nBytes
);
};
} else {
console.log("No cryptographically secure randomness source available");
}
})(CryptoJS);
,并像这样使用:
var iv = CryptoJS.lib.WordArray.random(128/8);
<标题>键密钥更棘手,因为它需要保密。基本方法是:
让用户键入服务器上也存在的密码,并通过例如使用CryptoJS也提供的PBKDF2从密码中派生密钥。完全安全,只要你使用TLS和开发人员不更改代码。
标题>