2010-08-23 3 views
3

나는 자바로 간단한 AES 암호화를하고있는 중이 야 :C 프로그램이 해독 된 텍스트에 패딩없이 해독 할 수 있도록 Java에서 문자열을 암호화 하시겠습니까?

Cipher cipher = Cipher.getInstance("AES"); 
cipher.init(Cipher.ENCRYPT_MODE, getAES128SecretKey()); 
byte[] encrypted = cipher.doFinal(input); 

출력 16 진수로 변환하고 데이터베이스에 저장됩니다.

이후 프로세스 (C/C++로 작성된 프로세스)가 따라 와서 16 진수를 읽고이를 바이트로 변환하고 해독합니다.

분명히 C 구현은 텍스트를 올바르게 해독하지만 불필요한 끝에 추가 바이트를 유지합니다.

예를 들어

(진짜 값) :

Java: encrypt("eric") -> 1234567890FFFFFF1234567890FFFFFF (hex) 
Java: decrypt("1234567890FFFFFF1234567890FFFFFF") -> "eric" 
    C: decrypt("1234567890FFFFFF1234567890FFFFFF") -> "eric XXXX XXXX XXXX" 

나는 C의 암호 해독 알고리즘과 그것이 내가 자바에 널 (NULL) 종료 문자 '\0'를 추가 제안 암호화하기 전에 바이트있다 이용하여 파티를 보유하고 있지 않습니다. 내 질문은, 그게 효과가 있고 그 생각을 즐겁게해야한다는 것인가?

Padding error when using AES encryption in Java and decryption in c 질문에 대한 첫 번째 대답 ("받아 들일 수없는", 나에게 맞는 것 같습니다)을 읽으면 패딩 크기를 명시 적으로 인코딩하는 것이 올바른 방법입니다.

그러나 문자열이 C로 암호화되고 C에서 해독되면 어떻게 될까요? 이제 C로 암호화 된 문자열에 C에서 해독 할 때 문제가 발생하고 Java 암호화 된 문자열 인 것처럼 채우기가 제거됩니까? 아니면 이것은 문제가 아닌가?

+1

자바와 C는 같은 질문입니다. 할리와 세발 자전거를 비교하는 것과 같습니다 ... 자바는 세발 자전거입니다. –

+0

@Matt - Java는 적어도 그곳에서 한 사람만큼 멋진 곳입니다. 면도기 스쿠터에 모든 엉덩이 아이들이 지금 타고 있습니다 ...;) – Eric

답변

1

암호화/암호 해독 프로세스는 대부분 관련성이 없습니다. 결국, 나오는 것은 나오는 것과 동일해야합니다. 문제는 파일에 쓸 때 String 객체를 나타내는 바이트가 어떻게 보이는지입니다.

빠른 테스트는 java가 문자열을 스트림에 쓸 때 문자열이나 스트림이 null로 끝나지 않는다는 것을 확인합니다. 다음 코드를 고려하십시오.

import java.io.FileWriter; 
import java.io.IOException; 

public SimpleStringIoTest 
{ 
    public static void main (String[] args) throws IOException 
    { 
    String message = "Raw Java String"; 
    FileWriter fileWriter = new FileWriter("javaoutput.bin"); 
    fileWriter.write(message); 
    fileWriter.close(); 
    } 
} 

다음을 생성하는 파일의 16 진수 덤프를 수행합니다.

00000000 52 61 77 20 41 61 76 61 20 53 74 72 69 6e 67  Raw Java String 

따라서 암호화하면 15 바이트의 암호화 된 문자열로 끝나고 15 바이트의 암호화 된 패딩이 블록됩니다. 해독 할 때 문자열뿐만 아니라 일반 텍스트 패딩을 가져오고 일반 텍스트의 길이를 알고 있거나 일반 텍스트 터미네이터가 내장되어 있지 않으면 일반 텍스트가 끝나는 위치를 알 수있는 방법이 없습니다.

NUL ('\ 0')을 종결 자로 사용하는 것은 C가 문자열의 끝을 표시하는 데 사용하는 종결 자이기 때문에 의미가 있습니다. ony 가능한 문제는 이미 문자열에 NUL이 어떻게 든 발생할 수있는 경우입니다. 이것이 아마도 C/C++ 프로그램에서 다른 문제를 일으킬 것이라는 점을 감안할 때 저는 의심 스럽지만 문제라면 항상 벗어날 수 있습니다.

아, 나는 다음과 같이 messages을 변경 검사 :

00000000 52 61 77 20 41 61 76 61 20 53 74 72 69 6e 67 00 Raw Java String 
+0

감사합니다. 감사합니다. 그래서, "내가 \ 0 추가 즐겁게해야합니까?" === 올바른 질문이 아닙니다. :) 코드 깊숙이 파고 들자 C-impl은 패딩 값을 패딩 값으로 사용했습니다. \ 0에 대한 요청은 개발자가 패딩을 제거하는 방법을 모르고서 \ 0을 불필요하게 만들었 기 때문에 발생했습니다. – Eric

+2

@ Eric : 패딩 값을 패딩 값으로 사용하는 것은 상당히 표준 적입니다. 유일한 문제는 서로 다른 일반 텍스트에 충돌 가능성이있는 암호문 충돌이 발생할 수 있다는 것입니다. 평문 "pad"와 "pad1"을 생각해보십시오. 32 비트 블록 크기를 가정하고 NUL 터미네이터가 없으면 동일한 암호문으로 암호화됩니다. 그 암호문을 감안할 때 어느 것이 올바른 일반 텍스트인지 어떻게 알 수 있습니까? 명시 적 종결자를 추가 할 때이 문제가 발생하지 않습니다. – torak

1

AES는 블록 암호이므로 암호화 할 데이터를 16 바이트로 채워야합니다. C 코드는 패딩을 처리하지 않으므로 아마도 암호화하는 동안 오류가보고되거나 '기본'패딩을 추가 할 것입니다. 더 나은 방법은 직접 패딩을 추가하는 것입니다.

+0

@Nickolay - C면 수정에 대한 투표와 같습니다. – Eric

+0

@ Eric : C 측에서이 문제를 안정적으로 해결할 수있는 정보가 충분하지 않은 것처럼 보입니다. 문자열 길이 또는 신뢰할 수있는 종결 자에 대한 선험적 지식이 없으면 일반 텍스트를 패딩과 구별 할 수 있다고 생각하지 않습니다. – torak

+0

또한 길이가 1, 2, 3, 4 ... 15, 16 인 문자열을 전달하고 Java 쪽에서 어떤 패딩이 추가되는지 확인하십시오. –

1

문자열 문제 및 NULL 패딩의 진수 덤프를 제공는 혼란과 잠재적으로 무관하다. Java는 표준 패딩 방식 (PKCS # 5)에서 까지 명확하게을 사용하여 해독기가 최종 블록의 몇 바이트를 버려야하는지 알 수 있습니다. 이것의 C 측은 또한 어떤 계획을 사용합니다. 그 계획이 무엇인지 알아야합니다. 나는 당신이 C decryptor에 의해 예상되는 패딩 알고리즘을 알 때까지 '\ 0'으로 패딩을 시도하는 것을 피할 것이다.

또한 기본값을 사용하는 대신 Cipher.getInstance() 메서드에서 패딩 및 모드를 명시 적으로 요청해야합니다. 예를 들어 Sun JCE 공급자를 사용하는 경우 사용량은 Cipher.getInstance("AES/CBC/PKCS5PADDING")과 같습니다. 이는 탁월한 선택입니다.

+0

감사합니다. 우리가 (동일한 프로젝트에서 작업하는 두 팀이 다름을 의미 함) 양쪽 끝을 소유하고 있기 때문에 해결책을 찾는 것이 좋습니다. 모든 사람이 언어에 상관없이 모든 암호화 장치/암호 해독기 솔루션에 대한 PKCS # 5 패딩 방식을 따르는 한 우리는 잘 수행해야합니다. – Eric

관련 문제