2013-09-27 78 views
0

關於AES有很多問題,但我有以下問題。 我目前使用以下AES實現到數據如何從AES-256切換到AES-128?

byte [] PRFkey = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; 
byte [] plaintext = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; 

SecretKeySpec encryptionKey=new SecretKeySpec(PRFkey, "AES"); 
Cipher cipher=Cipher.getInstance("AES"); 
cipher.init(Cipher.ENCRYPT_MODE, encryptionKey); 
byte[] encryptedData=cipher.doFinal(plaintext); 

加密和事實證明,結果是32個字節(256位)。所以我使用AES-256。這個實現會讓我放慢速度。我怎樣才能切換到AES-128?我不需要任何填充或操作模式或密鑰散列。

預先感謝您。

+0

注意:要遵循普通的Java命名實踐,'PRFkey'不應該以大寫字母開頭。這使它看起來像一個類型的名稱。 –

+1

不要將密鑰長度與塊大小混淆 - AES-256採用256位密鑰,但其塊大小爲128位,就像AES-128一樣。 AES標準只定義了128位塊大小,儘管原始Rijndael密碼也定義了256位塊大小。 – ntoskrnl

回答

3

您已經在使用128位AES。這取決於你傳遞給Cipher.init()的密鑰的長度,在你的例子中這是16個字節(128位)。

輸出的大小將取決於您的填充模式(以及輸入數據的大小)。由於您忽略指定操作模式或填充,因此您的JCE提供商可能默認爲"AES/ECB/PKCS5Padding"。 PKCS#5填充將始終爲輸出大小添加一個附加塊,因此您收到了32個字節的輸出,而不是16個字節。

絕不允許您的提供商爲您選擇默認值。相反,明確指定模式和填充:

Cipher cipher=Cipher.getInstance("AES/ECB/NoPadding"); 
cipher.init(Cipher.ENCRYPT_MODE, encryptionKey); 
byte[] encryptedData=cipher.doFinal(plaintext); // will be 16 bytes 

只要記住,如果你沒有指定填充,輸入數據必須始終16個字節的確切多。另請注意,ECB模式具有相同明文值將產生相同密文值的屬性。這在密碼系統中很少需要。

1

在堆棧溢出here上提出了一個類似的問題,它會幫助您提供您正在查找的信息。重要的一點是,The JCA Reference Guide表示:

(創建密碼對象)如果沒有指定模式或填充,則使用模式和填充方案的提供程序特定默認值。例如,SunJCE提供程序使用ECB作爲默認模式,並使用PKCS5Padding作爲DES,DES-EDE和Blowfish密碼的默認填充方案。這意味着對於SunJCE提供者:Cipher.getInstance(「DES」)和Cipher.getInstance(「DES/ECB/PKCS5Padding」)是等價的語句。

因此,由於您只是將「AES」指定爲轉換,因此用於Oracle JDK 7的AES的默認密碼是「AES/ECB/PKCS5Padding」,link

此外,Cipher類定義了轉換「AES/ECB/NoPadding」,它將爲您的encryptedData提供未填充的16字節值。 ECB是AES的默認模式,您也可以選擇「AES/CBC/NoPadding」。