0

파일에서 텍스트 암호를 입력하고 그 위에 AES 암호화를 적용하고 나중에 암호를 해독합니다. 내가 처음 해보니, 5 번 중 4 번 (암호화 해독 성공)이 올바르게 실행되었지만 1 번, BadPaddingException이 발생했습니다. 나는이 문제를 해결하기 위해 필요한유효하지 않은 키 예외

//ABCD is class name 
public static void enc(String fileName, String pwd) { 
    try { 
     Properties prop = new Properties(); 
     InputStream input = ABCD.class.getClassLoader().getResourceAsStream(fileName); 
     prop.load(input); 
     input.close(); 
     URL url = ABCD.class.getClassLoader().getResource(fileName); 

     FileOutputStream outputStream = new FileOutputStream(url.getPath()); 
     KeyGenerator key = KeyGenerator.getInstance("AES"); 

     key.init(128); 
     SecretKey aesKey = key.generateKey(); 
     String newkey = new String(Base64.encode(aesKey.getEncoded()).getBytes("UTF-8")); 

     Cipher aesCipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); 

     aesCipher.init(Cipher.ENCRYPT_MODE, aesKey); 
     byte[] clear = pwd.getBytes("UTF-8"); 
     byte[] cipher = aesCipher.doFinal(clear); 
     String encPwd = new String(cipher); 
     prop.setProperty("password", encPwd); 
     prop.setProperty("secKey", newkey); 
     prop.store(outputStream, null); 
     outputStream.close(); 
    } catch (Exception e) { 
     System.out.println(e); 
    } 
} 

public static String dec(Properties prop, String fileName) { 

    String decPwd = ABCD.map.get(fileName); 
      try { 
      String newkey = prop.getProperty("secKey"); 
      StringBuilder pwd; 
      byte[] newkeybuff = Base64.decode(newkey.getBytes("UTF-8")); 
      SecretKey key = new SecretKeySpec(newkeyuff, "AES"); 
      Cipher aesCipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); 
      aesCipher.init(Cipher.DECRYPT_MODE, key); 
      pwd = new StringBuilder(prop.getProperty("password")); 
      byte[] cipher = aesCipher.doFinal(pwd.toString().getBytes()); 
      decPwd = new String(cipher); 
     } catch (Exception e) { 
      System.out.println(e); 
     } 
     ABCD.map.put(fileName, decPwd); 
    return decPwd; 
} 

: 다음은 내가 쓴 것입니다. 어딘가에, 나는 BadPaddingExcpetion이 실제로 바이트가 사용되어야하는 대신에 String으로 수행 된 연산 이후에 발생한다는 것을 읽었다. 따라서 코드를 다음과 같이 변경했습니다.

public static void enc(String fileName, String pwd) { 
    try { 
     Properties prop = new Properties(); 
     InputStream input = ABCD.class.getClassLoader().getResourceAsStream(fileName); 
     prop.load(input); 
     input.close(); 
     URL url = ABCD.class.getClassLoader().getResource(fileName); 

     FileOutputStream outputStream = new FileOutputStream(url.getPath()); 
     KeyGenerator key = KeyGenerator.getInstance("AES"); 

     key.init(128); 
     SecretKey aesKey = key.generateKey(); 

     byte[] newkey=(Base64.encode(aesKey.getEncoded())).getBytes("UTF-8"); 

     Cipher aesCipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); 


     aesCipher.init(Cipher.ENCRYPT_MODE, aesKey,new IvParameterSpec(new byte[16])); 
     byte[] clear = pwd.getBytes("UTF-8"); 
     byte[] cipher = aesCipher.doFinal(clear); 

     prop.setProperty("password", Arrays.toString(cipher)); 
     prop.setProperty("secKey", Arrays.toString(newkey)); 

     prop.store(outputStream, null); 
     outputStream.flush(); 
     outputStream.close(); 

    } catch (Exception e) { 
    System.out.println(e); 
} 
} 

public static String dec(Properties prop, String fileName) { 

    String decPwd = ABCD.map.get(fileName); 
      try { 
      byte[] newkey=prop.getProperty("secKey").getBytes("UTF-8"); 
      byte[] pwd; 


      byte[] newkeybuff = Base64.decode(newkey); 
      SecretKeySpec key = new SecretKeySpec(newkeybuff, "AES"); 

      Cipher aesCipher=Cipher.getInstance("AES/CBC/PKCS5Padding"); 
      aesCipher.init(Cipher.DECRYPT_MODE, key,new IvParameterSpec(new byte[16])); 
      pwd = prop.getProperty("password").getBytes(); 

      byte[] cipher = aesCipher.doFinal(pwd); 

      decPwd=new String(cipher); 
      System.out.println("Decrypted pwd " + decPwd); 

     } 
     catch (Exception e) { 
    System.out.println(e); 
} 
     ABCD.map.put(fileName, decPwd); 

    return decPwd; 
} 

이제 InvalidKeyException이 발생합니다. 이번에는 키의 크기가 16 바이트 여야한다고 읽었습니다. 그러나 나는 이것을 적용하는 방법을 모른다. 이것에 대한 수정이 필요합니다!

+0

코드를 수정하기가 어렵습니다. 내가 사용하는 몇 가지 예를 들어에서 사용할 수있는 것이 좋습니다 http://stackoverflow.com/questions/15554296/simple-java-aes-encrypt-decrypt-example – pedrofb

답변

0

암호화 및 암호 해독을 위해 IV (초기화 벡터)가 동일한 지 확인해야합니다.

0

패딩 오류는 일반적으로 암호 해독에 실패했음을 의미합니다.

키가 전체 길이 (16, 24 또는 32 바이트)인지 IV가 전체 길이 (16 바이트)인지 확인하십시오. 키 또는 IV가 짧아지면 "무언가"로 채워질 것이고 그 사람은 일관성이 없기 때문에 그러한 패딩에 대한 표준은 없습니다.

getBytes("UTF-8")은 사용 된 문자에 따라 다른 길이의 바이트를 반환 할 수 있습니다.

IV에 new IvParameterSpec(new byte[16])을 사용하면 IV가 임의의 바이트 여야합니다. IV를 처리하는 일반적인 방법은 암호화 된 임의의 IV를 생성하여 암호화 된 데이터 앞에 추가하는 것입니다. 비밀로 할 필요가 없으며 미리 인코딩하여 해독 할 수 있습니다.

관련 문제