2015-02-10 162 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