2015-03-30 288 views
8

我在一個基於Web 文本加密和解密項目在Eclipse上工作(以下Struts 2中)如何解決無效的AES密鑰長度?

每當我輸入密碼,純文本,我得到一個無效的AES密鑰長度錯誤。

服務類(SymAES.java)

package com.anoncrypt.services; 

import java.security.Key; 
import javax.crypto.Cipher; 
import javax.crypto.spec.SecretKeySpec; 

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

public class SymAES 
{ 
    private static final String ALGORITHM = "AES"; 
    private static byte[] keyValue= new byte[] { 'T', 'h', 'i', 's', 'I', 's', 'A', 'S', 'e', 'c', 'r', 'e', 't', 'K', 'e', 'y' }; 

    public String encode(String valueToEnc) throws Exception { 
     System.out.println("The Key byte value"+keyValue); 

     Key key = generateKey(); 
     Cipher c = Cipher.getInstance(ALGORITHM); 
     c.init(Cipher.ENCRYPT_MODE, key); 
     byte[] encValue = c.doFinal(valueToEnc.getBytes()); 
     String encryptedValue = new BASE64Encoder().encode(encValue); 
     return encryptedValue; 
    } 

    public String decode(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 { 
     //System.out.println("passs value"+pass); 

     System.out.println("The Key byte value instde genkey"+keyValue); 
     Key key = new SecretKeySpec(keyValue, ALGORITHM); 
     return key; 
    } 

    public void start(String passcode)throws Exception 
    { 
     keyValue = passcode.getBytes(); 
     System.out.println("passcode"+passcode);  
     System.out.println("The Key byte value inside start"+keyValue); 
    } 
} 

這裏是Action類(SymEncrypt.java)

package com.anoncrypt.actions; 

import com.anoncrypt.services.SymAES; 

public class SymEncrypt { 
    private String encrypt; 
    private String encrypted; 
    private String password; 

    boolean TEMP; 

    public String execute() throws Exception { 
     SymAES ob=new SymAES(); 
     ob.start(getPassword()); 

     setEncrypted(ob.encode(getEncrypt())); 
     System.out.println("into action class "+getEncrypted()); 

     if(getEncrypted().equals(null)) 
      return "error"; 
     else 
      return "success"; 
    } 

    public String getEncrypted() { 
     return encrypted; 
    } 

    public void setEncrypted(String encrypted) { 
     this.encrypted = encrypted; 
    } 

    public String getEncrypt() { 
     return encrypt; 
    } 

    public void setEncrypt(String encrypt) { 
     this.encrypt = encrypt; 
    } 

    public String getPassword() { 
     return password; 
    } 

    public void setPassword(String password) { 
     this.password = password; 
    } 
} 

而這是誤差

java.security.InvalidKeyException: Invalid AES key length: 6 bytes 
    com.sun.crypto.provider.AESCrypt.init(AESCrypt.java:87) 
    com.sun.crypto.provider.ElectronicCodeBook.init(ElectronicCodeBook.java:93) 
    com.sun.crypto.provider.CipherCore.init(CipherCore.java:582) 
    com.sun.crypto.provider.CipherCore.init(CipherCore.java:458) 
    com.sun.crypto.provider.AESCipher.engineInit(AESCipher.java:307) 
    javax.crypto.Cipher.implInit(Cipher.java:797) 
    javax.crypto.Cipher.chooseProvider(Cipher.java:859) 
    javax.crypto.Cipher.init(Cipher.java:1229) 
    javax.crypto.Cipher.init(Cipher.java:1166) 
    com.anoncrypt.services.SymAES.encode(SymAES.java:35) 
    com.anoncrypt.actions.SymEncrypt.execute(SymEncrypt.java:24) 
    sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) 
    sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) 
    java.lang.reflect.Method.invoke(Unknown Source) 
    ognl.OgnlRuntime.invokeMethod(OgnlRuntime.java:870) 
    ognl.OgnlRuntime.callAppropriateMethod(OgnlRuntime.java:1293) 
    ognl.ObjectMethodAccessor.callMethod(ObjectMethodAccessor.java:68) 
    com.opensymphony.xwork2.ognl.accessor.XWorkMethodAccessor.callMethodWithDebugInfo(XWorkMethodAccessor.java:117) 
    com.opensymphony.xwork2.ognl.accessor.XWorkMethodAccessor.callMethod(XWorkMethodAccessor.java:108) 
    ognl.OgnlRuntime.callMethod(OgnlRuntime.java:1369) 
    ognl.ASTMethod.getValueBody(ASTMethod.java:90) 
    ognl.SimpleNode.evaluateGetValueBody(SimpleNode.java:212) 
    ognl.SimpleNode.getValue(SimpleNode.java:258) 
    ognl.Ognl.getValue(Ognl.java:494) 
    ognl.Ognl.getValue(Ognl.java:458) 
    com.opensymphony.xwork2.ognl.OgnlUtil$2.execute(OgnlUtil.java:309) 
    com.opensymphony.xwork2.ognl.OgnlUtil.compileAndExecute(OgnlUtil.java:340) 
    com.opensymphony.xwork2.ognl.OgnlUtil.getValue(OgnlUtil.java:307) 
    com.opensymphony.xwork2.DefaultActionInvocation.invokeAction(DefaultActionInvocation.java:423) 
    com.opensymphony.xwork2.DefaultActionInvocation.invokeActionOnly(DefaultActionInvocation.java:287) 
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:250) 
    org.apache.struts2.interceptor.DeprecationInterceptor.intercept(DeprecationInterceptor.java:41) 
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:244) 
    org.apache.struts2.interceptor.debugging.DebuggingInterceptor.intercept(DebuggingInterceptor.java:256) 
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:244) 
    com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor.doIntercept(DefaultWorkflowInterceptor.java:167) 
    com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98) 
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:244) 
    com.opensymphony.xwork2.validator.ValidationInterceptor.doIntercept(ValidationInterceptor.java:265) 
    org.apache.struts2.interceptor.validation.AnnotationValidationInterceptor.doIntercept(AnnotationValidationInterceptor.java:76) 
    com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98) 
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:244) 
    com.opensymphony.xwork2.interceptor.ConversionErrorInterceptor.intercept(ConversionErrorInterceptor.java:138) 
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:244) 
    com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:229) 
    com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98) 
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:244) 
    com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:229) 
    com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98) 
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:244) 
    com.opensymphony.xwork2.interceptor.StaticParametersInterceptor.intercept(StaticParametersInterceptor.java:191) 
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:244) 
    org.apache.struts2.interceptor.MultiselectInterceptor.intercept(MultiselectInterceptor.java:73) 
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:244) 
    org.apache.struts2.interceptor.DateTextFieldInterceptor.intercept(DateTextFieldInterceptor.java:125) 
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:244) 
    org.apache.struts2.interceptor.CheckboxInterceptor.intercept(CheckboxInterceptor.java:91) 
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:244) 
    org.apache.struts2.interceptor.FileUploadInterceptor.intercept(FileUploadInterceptor.java:253) 
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:244) 
    com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor.intercept(ModelDrivenInterceptor.java:100) 
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:244) 
    com.opensymphony.xwork2.interceptor.ScopedModelDrivenInterceptor.intercept(ScopedModelDrivenInterceptor.java:141) 
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:244) 
    com.opensymphony.xwork2.interceptor.ChainingInterceptor.intercept(ChainingInterceptor.java:145) 
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:244) 
    com.opensymphony.xwork2.interceptor.PrepareInterceptor.doIntercept(PrepareInterceptor.java:171) 
    com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98) 
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:244) 
    com.opensymphony.xwork2.interceptor.I18nInterceptor.intercept(I18nInterceptor.java:139) 
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:244) 
    org.apache.struts2.interceptor.ServletConfigInterceptor.intercept(ServletConfigInterceptor.java:164) 
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:244) 
    com.opensymphony.xwork2.interceptor.AliasInterceptor.intercept(AliasInterceptor.java:193) 
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:244) 
    com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor.intercept(ExceptionMappingInterceptor.java:189) 
    com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:244) 
    org.apache.struts2.impl.StrutsActionProxy.execute(StrutsActionProxy.java:54) 
    org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:564) 
    org.apache.struts2.dispatcher.ng.ExecuteOperations.executeAction(ExecuteOperations.java:81) 
    org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.doFilter(StrutsPrepareAndExecuteFilter.java:99) 
+0

我想你沒有無限強度轄區策略(未與JRE默認)Files.http://stackoverflow.com/questions/2568841/aes-encryption-java-invalid-key-length – kosa 2015-03-30 19:13:35

+0

我確實擁有無限強度管轄權策略jars @ nambari – 2015-03-30 19:20:07

+0

16個字節表示這裏有16個字符是非專業術語。 – 2017-12-18 03:48:29

回答

29

AES僅支持16,24或32字節的密鑰大小。您需要提供確切的金額,或者從您輸入的內容中獲得密鑰。

從密碼中派生密鑰有多種不同的方法。 Java爲此提供了一個PBKDF2實現。

我用埃裏克森的answer畫一個完整的畫面(僅適用於加密,因爲解密是相似的,但包括分裂密文):

SecureRandom random = new SecureRandom(); 
byte[] salt = new byte[16]; 
random.nextBytes(salt); 

KeySpec spec = new PBEKeySpec("password".toCharArray(), salt, 65536, 256); // AES-256 
SecretKeyFactory f = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1"); 
byte[] key = f.generateSecret(spec).getEncoded(); 

byte[] ivBytes = new byte[16]; 
random.nextBytes(ivBytes); 
IvParameterSpec iv = new IvParameterSpec(ivBytes); 

Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding"); 
c.init(Cipher.ENCRYPT_MODE, key, iv); 
byte[] encValue = c.doFinal(valueToEnc.getBytes()); 

byte[] finalCiphertext = new byte[encValue.length+2*16]; 
System.arraycopy(ivBytes, 0, finalCiphertext, 0, 16); 
System.arraycopy(salt, 0, finalCiphertext, 16, 16); 
System.arraycopy(encValue, 0, finalCiphertext, 32, encValue.length); 

return finalCiphertext; 

其他的事情要記住:

  • 請務必使用完全合格的密碼名稱。 AES在這種情況下不適用,因爲不同的JVM/JCE提供者可能使用不同的默認值來操作模式和填充。使用AES/CBC/PKCS5Padding。不要使用ECB模式,因爲它在語義上不安全。
  • 如果你不使用ECB模式,那麼你需要發送IV和密文一起。這通常是通過在密文字節數組前加IV來完成的。 IV會自動爲您創建,您可以通過cipherInstance.getIV()
  • 無論何時您發送某些東西,您都需要確保它不會一直被改變。正確使用MAC加密很難。我建議您使用CCM或GCM等認證模式。
+0

可以看到一個完整的例子(在這裏)(https://stackoverflow.com/a/44891805/1816580) – 2017-07-06 21:20:33

+1

要記住的另外一件事,對於超過128位(16字節)的密鑰大小,需要設置jre具有適當的權限。有關更多信息,請參閱此問題和答案:https://stackoverflow.com/questions/6481627/java-security-illegal-key-size-or-default-parameters。在可通過Cipher.getMaxAllowedKeyLength(「AES」)訪問的代碼中,該代碼返回一個不是字節的值。 – Brice 2018-02-28 12:02:42

-1

我面臨同樣的問題,然後我做了我的密鑰16字節,它現在正常工作。創建您的密鑰正好16個字節。它一定會奏效。

+0

你可能意思是16 **字節** – 2016-05-04 15:22:00

1

您可以驗證密鑰長度的限制:

int maxKeyLen = Cipher.getMaxAllowedKeyLength("AES"); 
System.out.println("MaxAllowedKeyLength=[" + maxKeyLen + "]."); 
相關問題