Java AES解密的有效结果在一个字节和仅一个字节之间存在差异的可能性有多大?
我需要用Java解密AES加密的字节。源数据以2个已知的验证字节开始,表示解密成功。出于某些协议原因,数据的长度小于255字节,如果已经加密数据的人需要,则假定数据被填充,使用前面提到的相同验证字节作为填充。我用可用的方法成功地解密了数十万条记录 现在我得到了一些记录,在成功(?)解密后,这些记录与预期的解密结果相差一个字节。当然不是验证字节;-),但另一个字节有一个非常特殊的,记录在案的含义。它总是相同的字节,总是相同的,恒定的错误值。很简单,例如,根据一些制造商特定的文档,我应该得到一个Java AES解密的有效结果在一个字节和仅一个字节之间存在差异的可能性有多大?,java,encryption,cryptography,aes,Java,Encryption,Cryptography,Aes,我需要用Java解密AES加密的字节。源数据以2个已知的验证字节开始,表示解密成功。出于某些协议原因,数据的长度小于255字节,如果已经加密数据的人需要,则假定数据被填充,使用前面提到的相同验证字节作为填充。我用可用的方法成功地解密了数十万条记录 现在我得到了一些记录,在成功(?)解密后,这些记录与预期的解密结果相差一个字节。当然不是验证字节;-),但另一个字节有一个非常特殊的,记录在案的含义。它总是相同的字节,总是相同的,恒定的错误值。很简单,例如,根据一些制造商特定的文档,我应该得到一个0x
0x47
,其中应该有0x44
简单地说,根据我所拥有的文档,结果中的所有其他内容都是正确的,并且是有意义的。现在的问题是,我得到的数据的制造商声称真正得到的是0x44
,而不是使用完全相同的输入数据得到的0x47
。我们有不同的意见
对于与AES/CBC/NoPadding一起使用的解密,在我的应用程序的调试器中,我可以看到在调用后,我的结果数据中已经有错误的0x47
。因为我在我的方法中没有发现任何错误,所以我决定测试其他AES解密程序,并发现3个(!)不同的实现,它们声称我对完全相同的输入数据有完全相同的结果:
- openssl enc-d-aes-128-cbc-iv“…”-K“…”-p-nopad-in-in.bin-out.bin
WTF?!:-) 在CBC模式下,使用密钥对每个密码文本块进行解密,然后将该结果与前一个密码文本块异或,以恢复纯文本 因为这是一个简单的异或操作,所以翻转前一个密文中的位将翻转当前纯文本块中的相应位。(当然,用翻转的位解密数据也会完全破坏之前的纯文本块。)
解密第一个密文块时,没有“上一个”密文块。这就是初始化向量的作用。它充当密文的第0块,如上所述,对IV的更改将导致第一个纯文本块中的逐位更改。在这种情况下,第一个块中似乎有不正确的字节,因此是由不正确的IV引起的 在回答评论的基础上扩展:
IV与第一个数据块异或,请参阅。在加密时,IV的单个字节(或位)更改将影响所有字节,但在解密时,它只影响与IV中不正确的字节(或位)相对应的第一个块中的字节(位) 另一种常见的方法是将IV预先发送到加密数据,这避免了必须通过另一个通道/方法共享IV以确保其正确
这确实表明验证方案很差。更好的方案考虑所有加密字节,通常是加密数据的HMAC。但在计算受限的环境中,CRC甚至校验和可能就足够了。IV与第一个数据块异或,请参阅。您没有指定加密模式,我假设是CBC模式。在加密时,单个字节会影响所有字节,但在解密时,它只影响IV中不正确的字节。