2009-08-04 2 views
8

Java Cipher 및 AES를 사용하여 암호화/암호 해독을 구현 중입니다. doFinal()에 대한 호출시 5 바이트가 추가된다는 점을 제외하면 모든 것이 잘 작동합니다. 그래서, 나는 올바르게 추가 된 5 바이트의 추가 된 문자열로 끝난다.자바 cipher.doFinal() 추가 바이트 쓰기

이유는 16 바이트 블록 전체가 쓰여지고 있기 때문입니다. 나는 마지막 16 바이트 블록을 포함하여 3 개의 16 바이트 블록을 썼다. 암호화 된 입력 파일은 64 바이트입니다. 암호화되지 않은 텍스트는 43 바이트 여야합니다.

doFinal에 대한 문서는 출력 버퍼에 기록 된 바이트 수를 반환 할 수 있음을 나타냅니다. 그러나 그것은 0,16,16,16입니다. 나는 모든 형태의 doFinal을 시도하고 업데이트하고 아무런 행동 변화를주지 않는다.

대부분의 알고리즘이 작동하는 방식이므로 전체 블록을 작성한다는 의미가 있습니다. 그러나 출력 데이터의 크기를 알려주지 않는 경우 초과 데이터를 방지하려면 어떻게해야합니까?

다른 알고리즘을 사용해야할까요? AES256은 필수 사항이지만 다른 블록 유형이나 패딩 유형이 올바른 바이트 수를 쓸 수 있는지 궁금합니다.

어떤 안내? (일부) 간결 냈다

: 암호 해독 루틴의

decryptCipher = Cipher.getInstance("AES"); 
decryptCipher.init(Cipher.DECRYPT_MODE, aesKey); 

사업 부분입니다. 모든 블록 암호 바와 같이

long bytesToRead = inputFile.length(); 

    while ((inLen = in.read(buffer)) > 0) { 
     int bytesOut = 0; 
     byte[] cryptBytes = null; 
     int outLen = cipher.getOutputSize(inLen); 
     cryptBytes = new byte[outLen]; 

     if (bytesToRead <= buffer.length) { 
      try { 
       bytesOut = cipher.doFinal(buffer, 0, inLen, cryptBytes, 0); 
      } catch (ShortBufferException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
     } else 
      try { 
       bytesOut = cipher.update(buffer, 0, inLen, cryptBytes, 0); 
      } catch (ShortBufferException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 

     out.write(cryptBytes, 0, bytesOut); 
     bytesToRead -= inLen; 

    } 
    try { 
     out.flush(); 
     in.close(); 
     out.close(); 
    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 

답변

14

Cipher.getInstance()를 호출 할 때 패딩 메커니즘을 지정해야합니다. 분명히 암호화 및 암호 해독시 모두 동일해야합니다. 예 : 패딩기구없이

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

는, 복호 측이 평문의 끝 (마지막 블록 이내)이되는 위치에 대한 어떤 정보도 가지고 있지 않다.

+0

대단히 고마워요. 그것으로 해결되었습니다. 나는 AES 만 지정했다면 기본적으로 ECB 블록 모드와 PCKS5Padding을 가지고 있다는 인상하에있었습니다. 맞지 않는 것 같아요. – wadesworld

+1

은 Java가 아닌 모든 AES 엔진에도 동일하게 적용됩니다. – Cheeso

1

AES는 블록 암호이다, 당연히 당신에게 전체 블록을 제공하는 것입니다.

자세한 내용은 Wikipedia article on AES을 참조하십시오.

"정확한 바이트 수"를 출력하고 싶다고하셨습니다. 올바른 바이트 수를 어떻게 결정 했습니까?

+1

그는 AES가 알고 있다고 생각합니다. 질문은 Java API를 사용하는 방법에 관한 것입니다. – skaffman

+0

해독 후 올바른 암호화되지 않은 크기를 알기 위해서는 스트림에 원래 크기를 써야합니다. –