简体   繁体   English

“NoPadding”参数在 Cipher 类中究竟做了什么?

[英]What exactly does the "NoPadding" parameter do in the Cipher class?

Java's Cipher class supports the transformations listed there . Java 的Cipher类支持此处列出的转换。 Among them are several NoPadding variants:其中有几个NoPadding变体:

  • AES/CBC/NoPadding (128) AES/CBC/NoPadding (128)
  • AES/ECB/NoPadding (128) AES/ECB/NoPadding (128)
  • AES/GCM/NoPadding (128) AES/GCM/NoPadding (128)
  • DES/CBC/NoPadding (56) DES/CBC/NoPadding (56)
  • DES/ECB/NoPadding (56) DES/ECB/NoPadding (56)
  • DESede/CBC/NoPadding (168) DESede/CBC/NoPadding (168)
  • DESede/ECB/NoPadding (168) DESede/ECB/NoPadding (168)

I assumed at first that "padding" here meant the method used to fill the last plaintext block, if the plaintext's size isn't a multiple of the cipher's block size.我首先假设这里的“填充”意味着用于填充最后一个明文块的方法,如果明文的大小不是密码块大小的倍数。

But in that case, how can a block cipher mode like ECB or CBC be used with "no padding"?但在这种情况下,如何使用“无填充”这样的分组密码模式(如 ECB 或 CBC)? Suppose that we use AES/ECB/NoPadding to encrypt a 250-bit message.假设我们使用AES/ECB/NoPadding来加密 250 位消息。 The first block of the plaintext is obviously the first 128 bits of the message.明文的第一个块显然是消息的前 128 位。 What are the last 6 bits of the second plaintext block?第二个明文块的最后 6 位是什么?

Well, first of all, you cannot feed Cipher - in any mode - a 250 bit message directly.好吧,首先,您不能直接向Cipher提供 250 位消息——在任何模式下。 The reason for that is that - like in most runtimes - the byte is the smallest amount of data that you can process.原因是 - 就像在大多数运行时一样 - 字节是您可以处理的最小数据量。 If you want to encode 250 bits you will have to think of an encoding of those bits in bytes (eg by indicating the bits in the final byte that you don't use, as performed for the value encoding of a DER encoded ASN.1 defined BIT STRING).如果您想编码 250 位,您将不得不考虑以字节为单位对这些位进行编码(例如,通过指示您不使用的最后一个字节中的位,如对 DER 编码的 ASN.1 的值编码所执行的那样)定义的位串)。


DER BIT STRING example for just 11 bits set to 1:仅 11 位设置为 1 的 DER BIT STRING 示例:

05 FF E0

here there are 5 unused bits in the final byte (which are set to value 0 ).这里的最后一个字节中有 5 个未使用的位(设置为值0 )。 So the first byte is simply sacrificed to indicate this fact - it's not part of the value.所以第一个字节只是为了表明这个事实而牺牲了——它不是值的一部分。


Second, even if the input would be a multiple of 8 bits, then you would still not be able to encrypt using NoPadding for ECB or CBC mode unless the input itself is already a multiple of the block size.其次,即使输入8 位的倍数,您仍然无法对 ECB 或 CBC 模式使用NoPadding进行加密,除非输入本身已经是块大小的倍数。 If you specify NoPadding then indeed no bytes are added (not even 00 valued bytes) so you'll get an IllegalBlockSizeException if the plaintext size is not a multiple of the block size (16 bytes for AES and 8 bytes for DES & DES-EDE).如果您指定NoPadding则确实没有添加字节(甚至不是00值字节),因此如果明文大小不是块大小的倍数(AES 为 16 字节,DES 和 DES-EDE 为 8 字节),您将获得IllegalBlockSizeException )。

The plaintext size is the amount of input bytes provided to the update and doFinal methods together.明文大小是一起提供给updatedoFinal方法的输入字节数。 The bytes for the blocks before the last one will be buffered where required - only the final count matters.最后一个块之前的块的字节将在需要时缓冲 - 只有最终计数很重要。


From the Cipher#doFinal documentation:来自Cipher#doFinal文档:

throws:抛出:

... ...
IllegalBlockSizeException - if this cipher is a block cipher, no padding has been requested (only in encryption mode), and the total input length of the data processed by this cipher is not a multiple of block size; IllegalBlockSizeException - 如果此密码是块密码,则未请求填充(仅在加密模式下),并且此密码处理的数据的总输入长度不是块大小的倍数; or if this encryption algorithm is unable to process the input data provided.或者如果此加密算法无法处理提供的输入数据。
... ...

Note that this is a this is a terrible description in my opinion: during decryption this exception will be thrown by doFinal regardless of the padding used (again, only for ECB and CBC modes) if the size is not a multiple of the block size.请注意,在我看来,这是一个糟糕的描述:在解密期间,如果大小不是块大小的倍数,则无论使用何种填充(同样,仅适用于 ECB 和 CBC 模式), doFinal都会抛出此异常。 The unpadding only happens after decryption by the block cipher and mode of operation after all.毕竟,取消填充仅在分组密码和操作模式解密后发生。

Of course, the output of ECB & CBC mode during encryption should always be a multiple of the block size, so that would mean that the ciphertext was truncated or otherwise altered before decryption.当然,加密期间 ECB 和 CBC 模式的输出应该始终是块大小的倍数,因此这意味着密文在解密之前被截断或以其他方式更改。


For GCM padding is not required (CTR mode encryption is used within), so NoPadding is the only realistic option, and any amount of data goes - but again the smallest element to be encrypted by Cipher is a byte.对于 GCM 不需要填充(其中使用了 CTR 模式加密),因此NoPadding是唯一现实的选择,并且任何数量的数据都可以传输 - 但再次由Cipher加密的最小元素是一个字节。 Even though the GCM algorith is specified in bits rather than bytes, this implementation doesn't support it.尽管 GCM算法是按位而不是字节指定的,但此实现不支持它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM