CryptoJS,检查AES密码是否正确

Sat*_*nix 1 javascript encryption cryptojs

var encrypted = CryptoJS.AES.encrypt("Message", "Secret Passphrase");

var decrypted = CryptoJS.AES.decrypt(encrypted, "Secret Passphrase");
Run Code Online (Sandbox Code Playgroud)

假设加密和解密阶段是分开的(发生在程序的不同部分),有什么办法可以检查"Secret Passphrase"解密阶段是否正确?

我注意到使用错误的密码短语进行解密将导致decrypted.toString()为空字符串.那么如果原始消息也是一个空字符串呢?是否有任何其他参数可用于检查密码是否确实正确?


旁注

我目前的解决方案:始终创建一个非空控制值,使用密码加密.如果控制值解密为"",则密码短语不正确.

编辑:结果我的解决方案不起作用.非常相似的密码短语将消息解密为不同的值,这些值仍然与空字符串不同.安全性没有受到损害,但我仍然无法确定密码是否正确.

this is my very cool key!并且this is my very cool key!!都返回一个字符串,即使只有第一个是用于加密的实际密码.

编辑2:从错误的密码短语返回的字符串无效UTF-8.因此,调用value.toString(CryptoJS.enc.Utf8)返回错误.我可以使用此错误来检查密码是否正确.不过,这个解决方案非常糟糕!

Dav*_*wen 6

您刚刚发现了消息机密性和消息完整性/身份验证之间的微妙但重要的区别.

机密性是您目前所做的事情,它确保在没有相关密钥的情况下无法在传输过程中读取消息,但无法确保在传输过程中消息未被更改(对早期加密系统的攻击涉及修改加密消息)注入或揭示有关加密系统的信息.你的问题就是这个问题的一个变种,如果你碰巧找到一个解密消息"投降"到"炸弹"的密钥,那么就没有办法知道他们的密钥被切换了.

完整性涉及确保解密的内容首先是实际加密的内容,并且还可以根据所使用的模型确保身份验证(加密它).完整性最好通过使用一种操作模式来支持它本质上支持它,例如GCM,但从粗略的一瞥,crypto-js不支持任何完整性模式.

这将为您提供手动方法,该方法需要生成并发送HMAC以及加密消息.

var message = "Message";
var passphrase = "Secret Passphrase";
var encrypted = CryptoJS.AES.encrypt(message, passphrase).toString();
var hmac = CryptoJS.HmacSHA256(encrypted, CryptoJS.SHA256(passphrase)).toString();
var transitmessage = hmac + encrypted;

//other side

var transithmac = transitmessage.substring(0, 64);
var transitencrypted = transitmessage.substring(64);
var decryptedhmac = CryptoJS.HmacSHA256(transitencrypted, CryptoJS.SHA256(passphrase)).toString();
alert(transithmac == decryptedhmac);
var decrypted = CryptoJS.AES.decrypt(transitencrypted, passphrase).toString(CryptoJS.enc.Utf8);
alert(decrypted.toString(CryptoJS.enc.Utf8));
Run Code Online (Sandbox Code Playgroud)

理论上,在HMAC调用之前,IV也应该加在加密消息之前,但我不知道如何使用crypto-js将IV恢复出去,我希望保持这个例子足够简单,除非你期望成为一个NSA的目标应该足够,因为IV已经修改了加密的消息.