我正在聊天室为多个用户加密邮件,每个用户可能有不同的加密和密钥/密码。因此,用户的密钥不适用于所有消息;返回错误。
var message ="secret message";
var encrypted = CryptoJS.AES.encrypt(message, "Secret Passphrase");
try {
var decrypted = CryptoJS.AES.decrypt(encrypted, "Secret Passphrase123").toString(CryptoJS.enc.Utf8);
if (decrypted.length > 0) {
alert(decrypted);
} else {
alert("false");
}
} catch(e) {
alert("false");
}
我目前正在捕捉错误,但有时解密会返回混乱的字母和符号。我目前这样做的方式效率不高。还有更好的方法吗?
答案 0 :(得分:6)
验证加密需要什么,请参阅Wikipedia。
基本上HMAC使用加密密钥加密数据并将结果附加到加密数据。
在解密之前,HMAC使用解密密钥对加密数据进行比较,并与附加的HMAC值进行比较。 (使用恒定时间比较功能。)
答案 1 :(得分:1)
在每封邮件的开头加上一个前缀,例如
encrypt("ABCD" + message);
然后在解密时,检查结果是否以"ABCD"
开头。
这不是万无一失的,因为不正确的解密可能会有相同的前缀,但这种可能性很小(为了减少机会,可以花更长的时间)。
然而,存在安全隐患,因为如果有人知道每条消息都以相同的前缀开头,它可以帮助他们分析并尝试打破加密(类似于在尝试打破简单时如何使用已知的字母频率) Caesar cypher)。
稍微好一点的方法是生成随机字符串,然后在加密前将其放在字符串中的两个位置。然后检查它们是否匹配。
random = random_string(10);
encrypt(random + message + random);
然后在解密后,检查第一个和最后10个字符是否匹配。
答案 2 :(得分:0)
这是有道理的,如果字节不完全适合CryptoJS.enc.Utf8
,大多数情况下你会收到错误。但有时,就像你说的那样,用户可能会幸运(或不幸)并提交一个解密为有效Utf8
字节的密钥,而且它并不真正知道其中的差异。我很想知道这种情况发生的频率。
我的解决方案是解析解密后的字符串并查找一些“指示符”,表明该消息看起来像一个普通的英语句子,而不是随机字符串的随机字符串。我要做的第一件事就是检查字符串中的空格数。这可能是唯一的最佳指标。
答案 3 :(得分:0)
我不是安全专家。您可以考虑在Information Security上提出问题以获得更好的意见(首先阅读他们的常见问题解答),但是:
1)您不应该首先尝试使用错误的密钥解密消息。这不是应该发生的事情。如果邮件是针对特定用户的,并且是使用其密钥加密的,那么请在邮件中包含 的信息,并在接收端检查邮件是否适合您< / EM>:
发送:
var message = { user: 1122, body: encryptedMessage };
send(message);
Recieving:
if (message.user == myUserId) {
decyptMessage(message.body);
} else {
// this message isn't for you
}
2)如果由于某种原因不起作用,那么您需要在消息中插入一些内容,以确认它是否已正确解除。 checksum可以达到这个目的:
发送:
var message = originalMessage + CalcChecksum(originalMessage);
send(encypt(message));
Recieving:
var decrypted = decrypt(message);
var msg = getTheBodyPartOfTheMessage(decrypted);
var chk = getTheChecksumPartOfTheMessage(decrypted);
if (chk == CalcChecksum(msg) {
// this is a good message
} else {
// this message isn't for you
}
您可以使用固定长度的校验和,例如,最后两个字符始终是校验和,或者您可以使用某些字符(否则会以其他方式出现)作为分隔符。
我更喜欢校验和比为每条消息添加前缀(或后缀)一些已知字符串的想法,因为每条消息的校验和都是不同的(好吧,不完全 - 但你不能预测它)。