有 填充 ,有 链接 。您应该首先获得正确的链接。
AES加密16字节的块,不多也不少。当您想加密一条可能超过16个字节的消息时,则必须决定如何将数据拆分为块并随后重新组合。基本拆分算法称为 ECB
:这是“拆分”为单独加密的块。已知ECB在实际数据方面的能力很弱,因为ECB会泄漏有关哪些明文块彼此相等的信息(它们将被相同地加密),并且这种冗余经常发生在“正常”数据中。
因此,需要以某种方式“随机化”数据块,以便隐藏数据冗余。该 CBC
模式执行通过“链”:一个块的处理取决于前一个块的加密的结果。即,将要加密的明文块与前一个块加密的输出组合(按位XOR)。
这里的重点是,要加密的第一个块(数据的前16个字节)没有“上一个块”,因此无需进行XOR处理。这可以通过选择“随机IV”(即16个随机字节的序列)来解决,该序列将用作XORing步骤的“块-1”。解密方必须知道IV(否则它将不知道对解密的块执行XOR运算,并且前16个字节的数据将无法理解)。好的一面是,静脉注射不需要保密。必须对其进行统一选择(不能为每个消息递增计数器),但通常可以沿加密消息本身“明文”发送。
因此,您不必担心IV,在Java或Ruby代码中我什么都看不到。通常,Java默认为ECB(因此完全没有IV)。如果Ruby在CBC中默认为“全零IV”(从概念上来说是不安全的),那么可以解密第一个块(将其写下来,它“可以正常工作”)是正常的,但同样正常它不适用于后续块。
因此,我建议您显式地使用CBC(在Java中,
"AES/CBC/PKCS5Padding"用作算法名称,而不是
"AES")并管理IV(必须将其传输;可以采用约定在加密消息之前连接IV)。
其他一些注意事项:
填充 是将一些数据添加到纯文本中,以便您具有适当的输入长度。CBC要求输入长度的长度必须是块大小(16个字节)的倍数。PKCS#5填充是一种流行的方法,通过该填充,您可以添加至少1个字节,最多16个字节,从而使它们全部具有值 n ,其中 n 是添加的字节数。然后,接收方可以(明确地)知道添加了多少个字节,并将其删除。Java可以为您添加填充,并且我想Ruby也可以根据需要自动处理填充。
在Java代码中,使用
key.getBytes()
。我想那key
是一个String
。知道会getBytes()
根据平台默认字符集对字符串进行编码,但在全球范围内并不总是相同。通过指定显式字符集,您将省去一些麻烦。另外,由于您想使用128位密钥,但是在Ruby端只能通过“ AES-256”获得某些东西,因此我假设您实际上在Java端使用了256位密钥。我的猜测是您的key
字符串是密钥的 十六进制 表示形式,为32个字符。key.getBytes()
不解释十六进制数字;它对字符本身进行编码,产生一个32字节的数组-和32字节,即256位,而不是128位。



