2017-10-19 1 views
1

나는 일반 텍스트를 AES-256-CBC으로 암호화 할 간단한 Java 프로그램을 작성하려고합니다. 클래스가 :Java에서 AES-256-CBC

import javax.crypto.Cipher; 
import javax.crypto.spec.IvParameterSpec; 
import javax.crypto.spec.SecretKeySpec; 

public class AesCBC { 
    private byte[] key; 
    private byte[] iv; 

    private static final String ALGORITHM="AES"; 

    public AesCBC(byte[] key, byte[] iv) { 
     this.key = key; 
     this.iv = iv; 
    } 

    public byte[] encrypt(byte[] plainText) throws Exception{ 
     SecretKeySpec secretKey=new SecretKeySpec(key,ALGORITHM); 
     IvParameterSpec ivParameterSpec=new IvParameterSpec(iv); 
     Cipher cipher=Cipher.getInstance("AES/CBC/PKCS5Padding"); 
     cipher.init(Cipher.ENCRYPT_MODE,secretKey,ivParameterSpec); 
     return cipher.doFinal(plainText); 
    } 

    public byte[] getKey() { 
     return key; 
    } 

    public void setKey(byte[] key) { 
     this.key = key; 
    } 

    public byte[] getIv() { 
     return iv; 
    } 

    public void setIv(byte[] iv) { 
     this.iv = iv; 
    } 
} 

는 가능한 사용이 있습니다 :

byte[] test="a".getBytes(); 

byte[] key=DatatypeConverter.parseHexBinary("b38b730d4cc721156e3760d1d58546ce697adc939188e4c6a80f0e24e032b9b7"); 
byte[] iv=DatatypeConverter.parseHexBinary("064df9633d9f5dd0b5614843f6b4b059"); 
AesCBC aes=new AesCBC(key,iv); 
try{ 
    String result=DatatypeConverter.printBase64Binary(aes.encrypt(test)); 
    System.out.println(result); 
}catch(Exception e){ 
    e.printStackTrace(); 
} 

내 출력 VTUOJJp38Tk+P5ikR4YLfw==,하지만 난이 명령을 실행할 때 :

/usr/bin/openssl enc -A -aes-256-cbc -base64 -K "b38b730d4cc721156e3760d1d58546ce697adc939188e4c6a80f0e24e032b9b7" -iv "064df9633d9f5dd0b5614843f6b4b059" <<< "a" 

내가 자바에 비해 diffrent 뭔가를 얻을 수 프로그램 ( Y65q9DFdR3k1XcWhA2AO2Q==). 안타깝게도 동일한 키와 같은 알고리즘을 사용하기 때문에 결과가 동일하지 않은 이유를 알 수 없습니다. iv. Java 프로그램이 제대로 작동하지 않는다는 것을 의미합니까? 어떤 도움을 주시면 감사하겠습니다.

+0

Java 및/또는 OpenSSL을 사용하여 Java 출력의 암호 해독을 시도 했습니까? OpenSSL로 다시 암호화하는 경우 동일한 출력을 얻습니까? 하단의 openssl enc 도움말 페이지 (https://wiki.openssl.org/index.php/Enc)에 따르면 "모든 소금물 옵션은 더 이상 사용되지 않습니다." 열쇠를 사용한다면 OpenSSL은 항상 결과에 소금을 칠 것입니다. – Jamie

답변

3

두 가지 방법 모두 올바르게 작동하지만 다른 것들을 암호화하고 있습니다.

여기의 문자열 구문 (<<<)은 문자열에 줄 바꿈을 추가합니다. 따라서 Java 출력은 "a"를 암호화 한 결과이고, 명령 행 출력은 "a \ n"(즉, 문자 a 다음에 개행이 있음)을 암호화 한 결과입니다.

명령 줄에서이 시도 :

printf "a" | /usr/bin/openssl enc -aes-256-cbc -base64 -K "b38b730d4cc721156e3760d1d58546ce697adc939188e4c6a80f0e24e032b9b7" -iv "064df9633d9f5dd0b5614843f6b4b059" 

결과가 VTUOJJp38Tk+P5ikR4YLfw==입니다, 자바 결과를 일치.

0

Java 결과가 정확합니다 (AES CALCULATOR 참조).

openssl 명령 줄 암호화가 잘못되었으므로 맨 페이지를주의 깊게 읽습니다.

필자는 수동으로 입력 데이터에 PKCS # 7 패딩을 추가했습니다.
또한 VTUOJJp38Tk+P5ikR4YLfw==은 16 진수입니다. 55350E249A77F1393E3F98A447860B7F