首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Cipher.doFinal输出尺寸

Cipher.doFinal输出尺寸
EN

Stack Overflow用户
提问于 2010-08-13 09:56:09
回答 2查看 7.2K关注 0票数 3

我正在使用javax.crypto在java中进行AES CBC解密。我使用以下密码类方法:

  • 初始化的public final void init (int opmode, Key key, AlgorithmParameters params)方法,
  • 用于解密数据的final int update(byte[] input, int inputOffset, int inputLen, byte[] output)方法,
  • 最后,我调用final int doFinal(byte[] output, int outputOffset)方法来完成解密。

我的查询是:我是否可以假设doFinal调用返回给我的数据的大小总是小于或等于AES块大小?文档将doFinal方法描述为:

“完成多部分转换(加密或解密)。处理以前的更新调用中可能已缓冲的任何字节。最后转换的字节存储在输出缓冲区中。“

但是它没有说输出缓冲区最多包含一个数据块。虽然我知道这是AES API的一般行为,这也是我的代码到目前为止所表现出来的行为,但这种假设是否总是成立的呢?

EN

回答 2

Stack Overflow用户

发布于 2010-08-13 10:26:37

通常(在Cipher类的上下文中),我不认为这样做是安全的。根据该javadocs方法的doFinal

如果输出缓冲区太小,无法保存结果,则会引发ShortBufferException。在本例中,使用更大的输出缓冲区重复此调用。使用getOutputSize确定输出缓冲区的大小。

因此,如果您正在“靠近”调用doFinal方法的点分配输出缓冲区,那么调用getOutputSize并分配适当大小的缓冲区是有意义的。工作完成了。

另一方面,如果您从“远远”传入一个缓冲区,该缓冲区被创建为与块大小完全相同的缓冲区,那么您可能会遇到更多的麻烦。只要getOutputSize方法返回适当的大小,密码实现返回大于块大小的输出是完全合法的(至少根据Java类的公共接口)。

实际上,如果您正在执行CBC解密,这不需要将所有块传递给update方法吗?在这种情况下,您应该从doFinal获得完整的明文输出,而不仅仅是一个块?

票数 3
EN

Stack Overflow用户

发布于 2010-08-13 12:19:11

一般来说,假设缓冲区只用于一个块是不安全的;当您查看详细信息时,您可能会看到它取决于填充的类型。使用通常的"PKCS#5“填充,至少会添加一个字节和最多n个字节(对于大小为n的块),因此解密系统可能会将自己限制为n字节的缓冲。其他一些类型的填充要复杂一些,例如CTS需要2n字节的缓冲。Java加密层现在似乎不支持CTS,但这可能会添加到将来的版本中。

给定Cipher.getOutputSize(len)额外的输入字节,len将给出最大输出大小。返回的值可能比实际返回的要大一些,特别是解密时,因为它取决于解密时实际会找到哪些填充字节。

安全的假设是,总解密消息长度不大于总加密消息长度(对称加密不涉及数据压缩)。因此,您可以维护两个计数器,一个用于输入数据字节(加密块),另一个用于获取的输出数据字节;差异将是从doFinal()获得的最大界限。但无论如何,这就是getOutputSize()所做的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3475761

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档