2012-05-31 436 views
11

當在程序下面運行時,我得到這個異常。無法弄清楚AES可以允許128 -256位密鑰的問題?獲取異常java.security.InvalidKeyException:無效的AES密鑰長度:29個字節?

Exception in thread "main" java.security.InvalidKeyException: Invalid AES key length: 29 bytes 
at com.sun.crypto.provider.AESCipher.engineGetKeySize(DashoA13*..) 
at javax.crypto.Cipher.b(DashoA13*..) 

在第20行

及彼的例外是程序

import java.security.Key; 

import javax.crypto.Cipher; 
import javax.crypto.spec.SecretKeySpec; 

import sun.misc.BASE64Decoder; 
import sun.misc.BASE64Encoder; 

public class AESEncryptionDecryptionTest { 

    private static final String ALGORITHM  = "AES"; 
    private static final String myEncryptionKey = "ThisIsSecurityKey"; 
    private static final String UNICODE_FORMAT = "UTF8"; 

    public static String encrypt(String valueToEnc) throws Exception { 
Key key = generateKey(); 
Cipher c = Cipher.getInstance(ALGORITHM); 
c.init(Cipher.ENCRYPT_MODE, key); //////////LINE 20 
byte[] encValue = c.doFinal(valueToEnc.getBytes()); 
String encryptedValue = new BASE64Encoder().encode(encValue); 
return encryptedValue; 
    } 

public static String decrypt(String encryptedValue) throws Exception { 
Key key = generateKey(); 
Cipher c = Cipher.getInstance(ALGORITHM); 
c.init(Cipher.DECRYPT_MODE, key); 
byte[] decordedValue = new BASE64Decoder().decodeBuffer(encryptedValue); 
byte[] decValue = c.doFinal(decordedValue); 
String decryptedValue = new String(decValue); 
return decryptedValue; 
} 

private static Key generateKey() throws Exception { 
byte[] keyAsBytes; 
keyAsBytes = myEncryptionKey.getBytes(UNICODE_FORMAT); 
Key key = new SecretKeySpec(keyAsBytes, ALGORITHM); 
return key; 
} 

public static void main(String[] args) throws Exception { 

String value = "password1"; 
String valueEnc = AESEncryptionDecryptionTest.encrypt(value); 
String valueDec = AESEncryptionDecryptionTest.decrypt(valueEnc); 

System.out.println("Plain Text : " + value); 
System.out.println("Encrypted : " + valueEnc); 
System.out.println("Decrypted : " + valueDec); 
} 

} 
+0

哪個語句生成異常? – aioobe

+0

c.init(Cipher.ENCRYPT_MODE,key); –

回答

29

AES允許128,192或256位的密鑰長度。這是16,24或32個字節。嘗試僅將mEncryptionKey的前16個字節作爲keyAsBytes

編輯:
雖然發生在我身後。我已經形成了一種習慣,我推薦的一種習慣是獲取密碼/密碼短語的SHA散列,並將其用作密鑰的源字節。哈希值保證密鑰數據的大小是正確的,不管密碼/密碼長度如何。您當前使用字符串字節的實現有兩個問題:

  • 如果有人使用短密碼,它將破壞您的密鑰生成。
  • 兩個不同的密碼,其前16個字節是相同的將創建相同的密鑰。

這些問題都可以通過使用散列消除。

看看這個班的buildKey()方法; https://github.com/qwerky/DataVault/blob/master/src/qwerky/tools/datavault/DataVault.java

+0

感謝Qwerky。一些更多的調查結果。當我給myEncryptionKey 16個字符長即128位長這個程序運行罰款,但是當我給它作爲24個字符長(192位長度)或32字符長(256位長度),然後我得到的錯誤爲「非法密鑰大小或默認參數「。如果我想要,我可以將密鑰長度設置爲256或192嗎? –

+1

要使用192或256,您可能需要啓用「無限密鑰強度」策略文件。這是由於美國的法律限制。看這裏; http://java.sun.com/developer/technicalArticles/Security/AES/AES_v1.html。在這個網站上搜索「非法密鑰大小或默認參數」,有幾個關於它的問題和答案。 – Qwerky

+0

在您的Datavault.java示例中,使用了BouncyCastleProvider,它不是標準的Java類。由於一些限制,我只需要使用standar java類。我可以在你指定的例子中使用BouncyCastleProvider instaed的一些其他實現嗎? –

1

該鍵使用隨機性作爲輸入,但是對於它的組成方式還存在stiill要求。您使用的SecretKeySpec構造函數用於將已經生成的密鑰加載到內存中。相反,使用KeyGenerator

KeyGenerator kg = KeyGenerator.getInstance(ALGORITHM); 
kg.init(128); 
SecretKey k = kg.generateKey(); 

另請注意,現在AES-128實際上被認爲比AES-256弱。它可能並沒有太大的不同,但其他地方的簡化可能會超過更長的密鑰大小所帶來的好處(更少的輪次)。

+1

嗨,約翰。我想使用自我分配的密鑰,因爲我將用作共享密鑰。我想使用已知和我所設定的密鑰而不是系統生成的密鑰。你可以拋出一些輸入,我可以如何使用AES中小於256位的任何長度的自分配密鑰? –

相關問題