2015-02-10 85 views
0

我有一个3DES 密码被这样初始化对象的端部产生的垃圾算法结束成功地:Java的3DES加密在加密数据

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上产生错误。

我们该如何防止密码注入这些额外的字节?

+0

数据长度是否总是8个字节的倍数? – 2015-02-10 18:27:09

+0

始终指定完全限定的密码字符串,因为不同的提供者可能具有不同的默认值。我怀疑你是'Cipher.getInstance(“DESede/CBC/PKCS5Padding”);'。 – 2015-02-10 18:28:40

+0

@ ArtjomB。不,作为纯文本并不总是。 – 2015-02-10 19:17:18

回答

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字节,否则将删除实际的明文字节。

+0

当你说“当明文大小是明文的倍数时,使用的填充将向填充0x08的明文添加另一个数据块”,我想你的意思是“当明文大小不是明文的倍数使用的填充将向填充0x08的明文添加另一个数据块。正确? – 2015-02-10 19:36:10

+0

不,PKCS5填充将明文填充到块大小的下一个倍数。如果明文已经是块大小的倍数,则算法无法知道在解密期间是否添加了填充,所以必须添加另一个块。 – 2015-02-10 19:37:40

+1

@DanielCalderonMori正如Artjom所说,ECB *不*安全。在上面的评论中,你说你使用它,如果你想实现它,你真的需要使用不同的模式。 – runDOSrun 2015-02-10 19:49:23