Java的3DES加密在加密数据的末尾生成垃圾

时间:2015-02-10 17:33:56

标签: java encryption 3des

我有一个3des Cipher 对象,初始化如下:

KeySpec keySpec= new DESedeKeySpec(bytesKey);
SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance("DESede");
SecretKey secretKey= secretKeyFactory.generateSecret(keySpec);
Cipher cipher = Cipher.getInstance("DESede");
cipher.init(modo, secretKey);

当此对象用于加密数据时,不会抛出任何异常,算法也会成功结束:

String unencryptedText = "192 character length text in clear....        ";
byte[] bytesUnencryptedText = unencryptedText.getBytes("UTF8");
byte[] bytesEncryptedData = cipher.doFinal(bytesUnencryptedText);

当我们查看doFinal生成的加密数据时,我们注意到返回了200个字节,而不是我们预期的192个字节。这些额外的8个字节采用以下六进制值:08。

前192个字节是正确的,我们已经能够解密它们并获得我们的原始数据。但是额外的8个字节在我们的HSM上产生错误。

我们如何阻止Cipher注入这些额外的字节?

1 个答案:

答案 0 :(得分:1)

DES的块大小为64位或8字节。当明文大小是明文的倍数时,所使用的填充将向填充有0x08的明文添加另一个数据块。这就是PKCS#5 / PKCS#7填充的工作原理。

您的HSM似乎期望不使用填充。此外,从注释中可以看出"DESede"默认为ECB模式,因此完全限定的密码将是:

Cipher cipher = Cipher.getInstance("DESede/ECB/NoPadding");

请注意,ECB模式在语义上不安全。如果可能的话,使用不同的模式,如CBC,使用HMAC而不是密文,或者只使用经过验证的模式,如GCM。

当您使用NoPadding时,明文填充0x00字节,您必须通过删除末尾的所有0x00字节来自己修剪解密的明文。为此,请确保明文实际上不包含0x00字节,否则您将删除实际的明文字节。