2015-03-30 3 views
8

Я работаю на веб-основе текста шифрования и дешифрования проекта затмения (после Struts 2)Как исправить неверную длину ключа AES?

Всякий раз, когда я ввожу пароль и простой текст, я получаю сообщение об ошибке Key Length Invalid 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); 
    } 
} 

Вот Класс действия (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

Я думаю, вы не Безлимитный политики Strength Юрисдикция (которые не по умолчанию с JRE) Files.http: //stackoverflow.com/questions/2568841/aes-encryption-java-invalid-key-length – kosa

+0

У меня есть неограниченная сила Jurisdiction Policy jars @ nambari –

+0

16 байтов означает 16 символов здесь в терминах непрофессионала. –

ответ

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 не подходит в таком случае, поскольку различные поставщики JVMs/JCE могут использовать разные значения по умолчанию для режима работы и заполнения. Используйте AES/CBC/PKCS5Padding. Не используйте режим ECB, потому что он не является семантически безопасным.
  • Если вы не используете режим ECB, вам необходимо отправить IV вместе с зашифрованным текстом. Обычно это делается путем префикса IV для байтового массива зашифрованного текста. IV автоматически создается для вас, и вы можете получить его через cipherInstance.getIV().
  • Всякий раз, когда вы отправляете что-то, вы должны быть уверены, что он не был изменен по пути. Трудно реализовать шифрование с MAC правильно. Я рекомендую вам использовать аутентифицированный режим, такой как CCM или GCM.
+0

Полный пример можно увидеть здесь (https://stackoverflow.com/a/44891805/1816580) –

+1

Дополнительную вещь, чтобы иметь в виду, для размера ключа более 128 бит (16 байт), jre необходимо настроить с соответствующими разрешениями. Для получения дополнительной информации см. Этот вопрос и ответ: https://stackoverflow.com/questions/6481627/java-security-illegal-key-size-or-default-parameters. В коде, доступ к которому можно получить через Cipher.getMaxAllowedKeyLength ("AES"), которые возвращают значение в битах, а не в байтах. – Brice

-1

Я столкнулся с той же проблемой, после чего я сделал свой ключ 16 байт, и теперь он работает правильно. Создайте свой ключ ровно по 16 байт. Это, безусловно, будет работать.

+0

Вы, вероятно, имеете в виду 16 ** байт ** –

1

Вы можете проверить ключ предел длины:

int maxKeyLen = Cipher.getMaxAllowedKeyLength("AES"); 
System.out.println("MaxAllowedKeyLength=[" + maxKeyLen + "]."); 
Смежные вопросы