我正在寻找一种方法,在 CryptoJS 中加密密码,然后在 php 中解密。我看过关于同一主题的其他帖子,但我需要有人解释所有 IV 和关键内容。
我的 CryptoJS 加密代码:
password = document.getElementById("usrp").value;
password = CryptoJS.AES.encrypt(password, <?php echo '"'.$_SESSION['adk'].'"'; ?>);
我正在寻找一种方法,在 CryptoJS 中加密密码,然后在 php 中解密。我看过关于同一主题的其他帖子,但我需要有人解释所有 IV 和关键内容。
我的 CryptoJS 加密代码:
password = document.getElementById("usrp").value;
password = CryptoJS.AES.encrypt(password, <?php echo '"'.$_SESSION['adk'].'"'; ?>);
您正在使用需要 IV 的 CBC 操作模式。如果您对所有密文都使用静态 IV,那么您就会错过加密的一个重要属性,即语义安全性。如果您使用相同的IV,攻击者可能会观察您的密文并确定您是否使用相同的密钥发送了相同的明文,因为密文将是相同的。
为了防止这种情况,您可以为您所做的每次加密生成一个随机 IV。IV 不一定是秘密的,但它必须是不可预测的。由于它不必保密,您可以简单地将其添加到密文中并在解密之前将其切掉,或者以结构化方式发送。您需要在解密期间使用 IV。否则,第一个块将与原始明文不同。
请记住,CryptoJS 的内部WordArray.random()
使用Math.random()
在密码学上是不安全的。最好使用更好的随机源。对于使用 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 并且开发人员不更改代码,就绝对安全。