2012-06-16 4 views
3

일부 간단한 텍스트를 암호화하고 해독하려고합니다. 그러나 어떤 이유로 저는 이상한 오류가납니다 : javax.crypto.BadPaddingException. JCE가 올바르게 패딩되어 있지 않은 바이트를 생성하는 이유는 무엇입니까?AES/CBC/PKCS5Padding 문제

나는 다음과 같은 코드가 있습니다

import javax.crypto.Cipher; 
import javax.crypto.KeyGenerator; 
import javax.crypto.SecretKey; 
import javax.crypto.spec.IvParameterSpec; 
import java.security.SecureRandom; 

public class SimplestTest { 
    public static void main(String[] args) throws Exception { 
     SecureRandom rnd = new SecureRandom(); 

     String text = "Hello, my dear! ... " + System.getProperty("user.home"); 
     byte[] textData = text.getBytes(); 

     IvParameterSpec iv = new IvParameterSpec(rnd.generateSeed(16)); 

     KeyGenerator generator = KeyGenerator.getInstance("AES"); 
     generator.init(128); 
     SecretKey k = generator.generateKey(); 

     Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding"); 
     c.init(Cipher.ENCRYPT_MODE, k, iv); 
     c.update(textData); 
     byte[] data = c.doFinal(); 

     System.out.println("E: " + data.length); 

     c = Cipher.getInstance("AES/CBC/PKCS5Padding"); 
     c.init(Cipher.DECRYPT_MODE, k, iv); 
     c.update(data); 

     System.out.println("R: " + c.doFinal().length); 
    } 

} 

을하지만 어떤 이유로 작동하지 않습니다. 이 예외로 인해 실패합니다.

E: 16 
Exception in thread "main" javax.crypto.BadPaddingException: Given final block not properly padded 
     at com.sun.crypto.provider.SunJCE_f.b(DashoA13*..) 
     at com.sun.crypto.provider.SunJCE_f.b(DashoA13*..) 
     at com.sun.crypto.provider.AESCipher.engineDoFinal(DashoA13*..) 
     at javax.crypto.Cipher.doFinal(DashoA13*..) 
     at SimplestTest.main(SimplestTest.java:31) 

무슨 일입니까? 데이터 크기는 16 바이트이지만 여전히 "제대로 채워지지 않았습니다"?

답변

4

Cipher.update는 byte []도 반환합니다. 따라서 해독 할 때 암호화 된 데이터의 일부가 누락됩니다. 다음과 같이 할 마지막 섹션을 업데이트 :

Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding"); 
c.init(Cipher.ENCRYPT_MODE, k, iv); 
byte[] someData = c.update(textData); 
byte[] moreData = c.doFinal(); 

System.out.println("E: " + (someData.length + moreData.length)); 

c = Cipher.getInstance("AES/CBC/PKCS5Padding"); 
c.init(Cipher.DECRYPT_MODE, k, iv); 
byte[] someDecrypted = c.update(someData); 
byte[] moreDecrypted = c.doFinal(moreData); 

System.out.println("R: " + (someDecrypted.length + moreDecrypted.length)); 
+0

고맙습니다. 이제 모든 것이 잘 작동합니다. –

4

당신은 update에 대한 호출을 포기하고 단지 암호화 또는 1 단계에서 암호 해독의 작업을 수행 doFinal에 직접 byte[] 데이터를 전달할 수 있습니다.