假设我们有一个带有可疑解密密钥的加密字节流。我想用密钥解密消息并验证结果。
如何验证结果?
关于纯文本唯一已知的事情是它应该包含一个人类语言段落(一个或多个)。我们不能在本文中再做任何其他的事情。
我想开发/使用一种算法来测试解密的输出,并让我预测解密是否成功。
该算法必须适用于所有人类语言(不会特定于一种语言)。
这可能吗?你觉得怎么样?
答案 0 :(得分:2)
解密密文(加密)字节数组以获取纯文本(解密)字节数组。
如果使用经过身份验证的加密,则使用错误密钥进行解密将彻底失败。
如果使用了正确的填充(PKCS#7 / PKCS#5),则使用错误密钥进行解密将失败,因为填充不会被正确解密。
使用正确的字符编码和 DecoderExceptionFallback
(Java中为CodingErrorAction.REPORT
)将字节数组解码为char数组。
如果解密的字节数组包含不表示有效字符的字节序列,则解码将失败。假设初始数据是相同编码中的正确文本,则只有在使用了错误的密钥时,解密的字节数组才会包含无效的字节序列。
实际上,前两个步骤会以非常高的概率暴露错误的密钥。
现在,在不太可能的情况下,当使用错误的密钥并且解密奇迹般地导致正确填充的数据并且解码的数据仅包含用于所选字符编码的有效字节序列时,您具有文本数据并且可以使用两个简单的(但仍然是经验性的,不需要字典或在线访问的想法:
Unicode General Category属性在确定字符类型时非常有用,而不是特定于单一语言,并且大多数正则表达式实现允许根据Unicode类别指定正则表达式模式。
首先,按Separator
和Punctuation
Unicode类别拆分文本。结果是一个"单词列表"没有空格和标点符号。
其次,将每个单词与Letter+
模式匹配。对于任何自然文本,与不匹配的单词匹配的单词的比率都很高。它对于一个特定构造的类似文本的乱码来说也可能很高,但对于一个随机的字符序列肯定会很低。
答案 1 :(得分:1)
您可以分析文本然后计算字母频率。如果字母频率是图表的方式,你可以说加密出错了。如果你将它与空格的出现混合在一起,你可以用一种合理的方式来说明加密是否成功。
答案 2 :(得分:0)
无法判断字节流是否包含人类语言中的消息而无需更多假设。首先,您绝对需要知道编码(或一些可能的编码)。
然后我99.9%肯定没有通用的方法来推断一大群(例如)ASCII-chars是否在任何人类语言中都有意义而不使用某种字典。如果你可以将它缩小到一个语言家族,也许你将能够检测到语法结构 - 但我真的只是猜测。即使有可能,设计启发式也不是一项微不足道的任务。
那就是说,我只能在评论中提出建议:使用维基百科!从中创建自己的字典或在线使用 - 无论哪种方式,我相信这是你最好的选择。