2014-12-08 115 views
2

以下是我的加密邏輯。雖然我的IV是16字節長,但我仍然遇到IV無效的錯誤。希望得到任何幫助AES 256位加密 - java.security.InvalidAlgorithmParameterException:錯誤IV長度:必須爲16字節長

@Override 
public String encrypt(String dataToEncrypt, String IV) throws Exception{ 
    if(encryptionKey.length() < 10){ 
     encryptionKey = generateEncryptionKey().toString(); 
    } 
    System.out.println("number of IV bytes is "+IV.length()+" "+IV); 
    Cipher cipher = Cipher.getInstance(encrpytionAlgo); 
    SecretKey key = new SecretKeySpec(encryptionKey.getBytes(Charset.forName("UTF-8")), "AES"); 
    cipher.init(Cipher.ENCRYPT_MODE, key,new IvParameterSpec(IV.getBytes(Charset.forName("UTF-8")))); 
    byte[] encryptedTextBytes = cipher.doFinal(dataToEncrypt.getBytes(Charset.forName("UTF-8"))); 
    return new Base64().encodeAsString(encryptedTextBytes); 
} 

IV和密鑰生成邏輯

@Override 
public String generateRandomIV(){ 
     Random random = new SecureRandom(); 
     byte[] iv = new byte[16]; 
     random.nextBytes(iv); 
     System.out.println("IV is "+Base64.encodeBase64(iv)+" "+ com.sun.jersey.core.util.Base64.base64Decode(new String(Base64.encodeBase64(iv)))+ " number of bytes is "+iv.length); 
     return new String(Base64.encodeBase64(iv)); 
} 

@Override 
public SecretKey generateEncryptionKey(){ 
    KeyGenerator aesKey = null; 
    try { 
     aesKey = KeyGenerator.getInstance("AES"); 
    } catch (NoSuchAlgorithmException e) { 
      e.printStackTrace(); 
    } 
    aesKey.init(256); 
    SecretKey secretKey = aesKey.generateKey(); 
    System.out.println("Encryption key is "+ new Base64().encode(secretKey.getEncoded())); 
    return secretKey; 
} 

下面是例外 異常堆棧跟蹤是行:
cipher.init(Cipher.ENCRYPT_MODE,鑰匙,新IvParameterSpec (IV.getBytes(Charset.forName( 「UTF-8」))));

java.security.InvalidAlgorithmParameterException: Wrong IV length: must be 16 bytes long 
at com.sun.crypto.provider.SunJCE_f.a(DashoA13*..) 
at com.sun.crypto.provider.AESCipher.engineInit(DashoA13*..) 
at javax.crypto.Cipher.a(DashoA13*..) 
at javax.crypto.Cipher.a(DashoA13*..) 
at javax.crypto.Cipher.init(DashoA13*..) 
at javax.crypto.Cipher.init(DashoA13*..) 
at com.intuit.platform.publiccloudaccess.core.services.EncryptionServiceImpl.encrypt(EncryptionServiceImpl.java:47) 
+0

我建議你保持你的IV作爲一個字節[]。通常,將UTF-8字符串轉換爲字節數組並不會爲每個字符提供一個字節。爲什麼你想要轉換到/從一個字符串的開銷呢? – Rob 2014-12-08 04:57:33

+0

感謝@Rob工作。 – outtoexplore 2014-12-18 18:24:04

回答

3

您將您的IV編碼爲Base64,然後從generateRandomIV返回。在使用它進行加密和解密之前,您必須將其解碼。

cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(java.util.Base64.Decoder.decode(IV.getBytes("UTF-8")))); 

Java 8提供了java.util.Base64類,用於獲取不同的Base 64編碼器和解碼器。

1

繼羅布的評論,

System.out.println("number of IV bytes is "+IV.length()+" "+IV); 

在這裏,你得到IV的長度字符串的條款。然而

cipher.init(Cipher.ENCRYPT_MODE, key,new IvParameterSpec(IV.getBytes(Charset.forName("UTF-8"))));  

這裏您提供的IV爲字節陣列和製作在字符串的千卡的IV爲16的長度並不能保證它的字節表示也是16個字節。所以Rob建議你最好將IV保存在字節數組中,並將其用作字節數組。

相關問題