2015-03-30 36 views
8

Tôi đang làm việc trên một mã hóa văn bản dựa trên web và dự án giải mã về nhật thực (sau Struts 2)Cách khắc phục độ dài khóa AES không hợp lệ?

Bất cứ khi nào tôi nhập mật khẩu và các văn bản đơn giản tôi nhận được một hợp lệ AES lỗi Chiều dài Key.

Dịch vụ Lớp (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); 
    } 
} 

Đây là Action Class (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; 
    } 
} 

Và đây là lỗi

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

Tôi đoán bạn không có giới hạn chính sách Strength Thẩm quyền (mà không được mặc định với JRE) Files.http: //stackoverflow.com/questions/2568841/aes-encryption-java-invalid-key-length – kosa

+0

Tôi có các chòm sao Chính sách quyền hạn không giới hạn sức mạnh @ nambari –

+0

16 byte có nghĩa là 16 ký tự ở đây theo các thuật ngữ của giáo dân. –

Trả lời

29

AES chỉ hỗ trợ kích thước khóa 16, 24 hoặc 32 byte. Bạn cần phải cung cấp chính xác số tiền đó hoặc bạn lấy được chìa khóa từ những gì bạn nhập.

Có nhiều cách khác nhau để lấy chìa khóa từ cụm mật khẩu. Java cung cấp một triển khai PBKDF2 cho một mục đích như vậy.

tôi đã sử dụng Erickson của answer để vẽ nên một bức tranh hoàn chỉnh (chỉ mã hóa, vì giải mã là giống nhau, nhưng bao gồm việc tách bản mã):

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; 

Những điều khác cần lưu ý:

  • Luôn sử dụng tên mã hóa đủ điều kiện. AES không thích hợp trong trường hợp này, bởi vì các nhà cung cấp JVM/JCE khác nhau có thể sử dụng các giá trị mặc định khác nhau cho chế độ hoạt động và đệm. Sử dụng AES/CBC/PKCS5Padding. Không sử dụng chế độ ECB, vì nó không an toàn về mặt ngữ nghĩa.
  • Nếu bạn không sử dụng chế độ ECB thì bạn cần gửi IV cùng với bản mã. Điều này thường được thực hiện bằng cách thêm tiền tố IV vào mảng byte bản mã. IV được tạo tự động cho bạn và bạn có thể tải nó qua cipherInstance.getIV().
  • Bất cứ khi nào bạn gửi một cái gì đó, bạn cần phải chắc chắn rằng nó không bị thay đổi trên đường đi. Thật khó để thực hiện một mã hóa với MAC một cách chính xác. Tôi khuyên bạn nên sử dụng chế độ được xác thực như CCM hoặc GCM.
+0

Một ví dụ đầy đủ có thể được nhìn thấy [ở đây] (https://stackoverflow.com/a/44891805/1816580) –

+1

Điều bổ sung cần lưu ý, đối với kích thước khóa trên 128 bit (16 byte), jre cần phải được thiết lập với quyền thích hợp. Để biết thêm thông tin, hãy xem câu hỏi và câu trả lời này: https://stackoverflow.com/questions/6481627/java-security-illegal-key-size-or-default-parameters. Trong mã có thể được truy cập thông qua 'Cipher.getMaxAllowedKeyLength (" AES ")' trả về một giá trị theo bit chứ không phải byte. – Brice

-1

Tôi đã gặp phải vấn đề tương tự, sau đó tôi đã tạo khóa 16 byte chính của mình và nó hoạt động bình thường ngay bây giờ. Tạo khóa của bạn chính xác 16 byte. Nó chắc chắn sẽ hoạt động.

+0

Bạn có thể có nghĩa là 16 ** byte ** –

1

Bạn có thể xác minh giới hạn độ dài chính:

int maxKeyLen = Cipher.getMaxAllowedKeyLength("AES"); 
System.out.println("MaxAllowedKeyLength=[" + maxKeyLen + "]."); 
Các vấn đề liên quan