1 回答
TA贡献1852条经验 获得超1个赞
如果只有 ECB / CBC 填充的最后一个块不同,那么您可以很确定使用了不同的块密码填充。要验证使用了哪个填充,您可以尝试(正如 Topaco 在问题下方的评论中所做的那样),或者您可以在没有填充的情况下解密密文。对于 Java,那将是"AES/CBC/NoPadding".
因此,如果您在给定密钥(和 IV)的情况下这样做,那么您将获得以下十六进制输出:
73733D62726F636B2670773D3132333435362674733D3230313930333034323334343331000000000000000000000000
显然这是零填充。
零填充有一个很大的缺点:如果您的密文以值为零的字节结尾,那么这个字节可能会被视为填充并从结果中删除。通常这对于由 ASCII 或 UTF-8 字符串组成的纯文本来说不是问题,但对于二进制输出可能会比较棘手。当然,我们在这里假设字符串不使用预期会出现在加密明文中的空终止符。
还有另一个较小的缺点:如果您的明文恰好是块大小,那么零填充就足够不标准了,因此有两种情况:
填充总是被应用并且需要被删除,这意味着如果明文大小正好是块大小的数倍,那么仍然会添加一个完整的填充块(所以对于 AES,你会有 1..16 零值字节作为填充);
仅在严格要求时才应用填充,这意味着如果明文大小正好是块大小的数倍,则不应用填充(因此对于 AES,您将有 0..15 个零值字节作为填充)。
因此,目前,对于加密,您可能必须测试预期/接受哪一个。例如,可用于 C# 和 Java 的 Bouncy Castle 总是(未)填充,而可怕的 PHP / mcrypt 库只在需要的地方填充。
当然,您始终可以执行自己的填充,然后"NoPadding"用于 Java。请记住,您永远不会取消填充超过 16 个字节。
一般警告:未经身份验证的加密不适合传输模式安全性。
- 1 回答
- 0 关注
- 182 浏览
添加回答
举报
