Java Card中没有AES密码的填充

时间:2016-01-27 10:33:47

标签: cryptography aes javacard

在JavaCard 2.2.2 API中,我可以看到一些对称密码是使用填充模式实现的,例如:

  

密码算法ALG_DES_CBC_ISO9797_M1提供使用DES的密码   外部CBC模式下的CBC模式或三重DES,以及填充输入数据   根据ISO 9797方法1方案。

但对于AES密码,没有可用的填充模式(ALG_AES_BLOCK_128_ECB_NOPADALG_AES_BLOCK_128_CBC_NOPAD)。

那么如何解释这个算法不支持它?

这些填充方法是否容易受到使用AES的已知攻击?

2 个答案:

答案 0 :(得分:3)

如果可用的其他填充模式取决于您使用的Java Card API以及特定Java Card的实现细节。

后来的API有:

由于模式和填充方法的爆炸,添加了特殊的getInstance方法。

较旧的API实现可能确实没有这些方法,但请再次检查可用性。

AES本身就是一种分组密码。不同的模式(如CBC)使用密码和填充 - 因此CBC_AES_PKCS7PADDING在某种意义上更合乎逻辑。因此,作为分组密码,AES不容易受到填充oracle攻击。

另一方面,CBC 易受填充oracle和其他明文oracle攻击。所以你应该保护你的IV和密文,例如:如果您需要针对这些攻击的保护,请使用AES-CMAC身份验证标记。

然而,这并不是不包括填充模式的原因。不同的填充模式are certainly present now

答案 1 :(得分:1)

不一定 - 只表示此算法不会自动填充输入数据。你必须自己做(可能将它填充到16个字节的倍数,因为这是AES需要的。)

  

那么如何解释这个算法不支持它?

我不确定,但请注意,有几种方法可以做到这一点,也许作者决定为您选择最合适的填充样式。

如果您想了解有关填充的更多信息,请考虑以下示例:

你必须加密一个单词"溢出"用AES。 首先,您必须将其转换为字节形式,因为这是AES操作的。

ASCII编码字符串"溢出"是

"6F 76 65 72 66 6C 6F 77 00"

(最后一个字节是字符串终止符,AKA \0或空字节) 不幸的是,这对于纯AES算法来说也是不够的,因为它可以在整个数据块上运行OLNY - 比如16字节数据块。 这意味着,您需要16-9 = 7个字节的数据。因此,您可以使用空字节将编码的字符串填充为完整的16字节数据。结果是

"6F 76 65 72 66 6C 6F 77 00 00 00 00 00 00 00 00"

现在您选择加密密钥并加密数据。 解密数据后,您将再次收到

"6F 76 65 72 66 6C 6F 77 00 00 00 00 00 00 00 00"

现在问题的症结在于:你怎么知道哪些字节最初在你的字符串中,哪些是填充字节? 在en / decrypting字符串的情况下,这非常简单,因为字符串(几乎)总是以空字节结束,并且在结尾处永远不会有多个连续的空字节。因此,很容易确定削减数据的位置。

有关"加密填充的样式的更多信息"你可以在这里找到:https://en.wikipedia.org/wiki/Padding_%28cryptography%29#Byte_padding