2017-11-27 18 views
0

안녕하세요, 저는 OpenSSL 명령을 사용하여 메시지를 암호화하고 해독합니다. 이제이 명령을 Java 코드에서 변환해야합니다. 다른 솔루션을 웹에서 제공했지만 코드 중 아무 것도 결과와 일치하지 않았습니다.OpenSSL AES/CBC 256 명령 출력이 java 코드 출력과 일치하지 않습니다.

참고 :

key="FB4FF1BA6F1FCC1A11B8B3910342CBD3A2BEAEB8F52E8910D9B25C0C96280EEA" 

# Getting 16 digits from the iv.txt file and putting it into the bin 
head -c 16 iv.txt > iv.bin 

# Converting iv.bin text into the HEXA value 
iv=`xxd -l 16 -p iv.bin` 

# encrypt without "-a" 
openssl enc -aes-256-cbc -K $key -iv $iv -in plainKey.txt -out encryptedKey.bin 

# printing encrypted results in base64 format this need to be matched with my java code. 
echo "<enc>"`cat encryptedKey.bin | base64`"</enc>" 

이 내가 자바에서 수행 한 것입니다 : 여기

는 의견을 내 과소 내에서 OpenSSL 명령입니다 사소한 변화 스택 오버 플로우 허용 대답에서이 코드를 I 다른 코드를 사용해 보았지만 여기서 모두 언급 할 수는 없습니다. 그렇게 예외를 생산)

import javax.crypto.Cipher; 
import javax.crypto.spec.IvParameterSpec; 
import javax.crypto.spec.SecretKeySpec; 
import javax.xml.bind.DatatypeConverter; 

public class Test { 

public static void main(String[] args) { 
    try { 
     runEncryption(); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
} 

private static void runEncryption() throws Exception 
{ 
    //String to be encrypted 
    String plainText = "[email protected]\n"; 

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

    // IV text 
    String iv = "C837E1B6C3D3A7E28F47719DE0C182C9"; 

    // getting 16 characters of iv text 
    iv = iv.substring(0,16); 

    // Value of key 
    String key = "FB4FF1BA6F1FCC1A11B8B3910342CBD3A2BEAEB8F52E8910D9B25C0C96280EEA"; 

    // Logic for converting 16 Digits of IV into HEX 
    StringBuffer hexString = new StringBuffer(); 
    for (int i=0;i<iv.getBytes().length;i++) { 
     String hex=Integer.toHexString(0xff & iv.getBytes()[i]); 
     if(hex.length()==1) hexString.append('0'); 
     hexString.append(hex); 
    } 

    // Seems something wrong here because if i am passing all the bytes to keySpe like key.getBytes() it is producing exception so i am passing 16 bytes as previous code was doing in SO 
    SecretKeySpec keySpec = new SecretKeySpec(hexToBytes(key), 0, 16, "AES"); 
    IvParameterSpec ivSpec = new IvParameterSpec(hexToBytes(hexString.toString())); 

    cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec); 
    byte[] encrypted = cipher.doFinal(plainText.getBytes("UTF-8")); 

    String encryptedBase64 = new String(DatatypeConverter.printBase64Binary(encrypted)); 

    System.out.println(""); 
    System.out.println("Encrypted base64 = " + encryptedBase64); 
} 

private static byte[] hexToBytes(String s) 
{ 
    int len = s.length(); 
    byte[] data = new byte[len/2]; 

    for (int i = 0; i < len; i += 2) 
     data[i/2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) + Character.digit(s.charAt(i + 1), 16)); 

    return data; 
}  
} 

나는 키 생성 오전 IV OpenSSL을 명령

openssl enc -aes-256-cbc -k secret -P -md sha1 

를 사용하여 난 (key.getBytes 같은 keySpec에 모든 바이트를 전달하고 경우 때문에 여기에 뭔가 잘못 보인다 이전 코드에서했던 것처럼 16 바이트를 전달 오전 코드 주석이이 언급 한 조언을주십시오.

+0

이 다른 문제 일 수 있지만, 먼저 같은 매개 변수를 가질 수 있습니다 -에서 OpenSSL은'AES-256 cbc'으로 사용되는 경우는, 효과적으로 AES-128 일을 16 키 바이트를 전달하고 있습니다. 다음 - 왜 당신은 16 진수/문자열 변환 자신을합니까? ( – gusto2

+0

[Java AES 128이 openssl과 다르게 암호화 됨] (http://stackoverflow.com/q/21086103/608639), [Java OpenSSL AES CBC 암호화] (http://stackoverflow.com/q/32508961/608639), [Java를 사용하여 openssl aes-128-cbc로 인코딩 된 문자열을 디코딩하는 방법은 무엇입니까?] (http://stackoverflow.com/q/31947256/608639), [Java를 사용하여 openssl aes-256- cbc는 제공된 키와 iv] (http://stackoverflow.com/q/15594518/608639) 등을 사용합니다. – jww

+0

일반적으로 ['EVP_BytesToKey'] (http://wiki.openssl.org/index.php/Manual:EVP_BytesToKey (3)) 이슈 중 하나입니다. [Java에서 제공하는 C++ 암호화] (http://stackoverflow.com/q/12920740/608639), [Java에서 OpenSSL로 생성 된 키 사용 방법] (http : // security.stackexchange.com/q/9600/29925), [Java openssl 암호화/암호 해독 키 생성] (http://stackoverflow.com/q/34502705/608639), [OpenSSL 명령과 호환되는 키 기능을위한 암호?] http://stackoverflow.com/q/9488919), [파일을 해독하는 방법 AES를 사용하여 openssl 명령으로 암호화 된 Java?] (http://stackoverflow.com/q/11783062) 등 – jww

답변

0

당신은

이의이 싶은 것은 코드에서

openssl enc -aes-256-cbc -K FB4FF1BA6F1FCC1A11B8B3910342CBD3A2BEAEB8F52E8910D9B25C0C96280EEA -iv 03B13BBE886F00E00000000000000000 -base64 -in input.txt 

당신이 (순간 태권도 연맹) 몇 가지 실수를 가지고 있다고 가정하자 코드에서 몇 가지 실수가 있습니다. 나는 기본적으로 당신을 위해 그들을 해결하지만,하지 않습니다

  1. 좀 정상적인 라이브러리를 사용하도록 조언 것 (예를 들어 평민 - 코덱, ..) 인코딩/진수에서 디코딩, 비록 지금까지 일하고있어 보인다

  2. 16 바이트 (128 비트)를 사용 중이며 AES-128을 효과적으로 수행하는 키입니다. 키가있는 AES-256과 iv 256 비트 길이 (32 바이트)를 사용해야합니다. 둘 다 16 바이트로 잘라서 openssl에서 사용하는 값과 다름

  3. 주요 분해 점 : IvParameterSpec ivSpec = new IvParameterSpec(hexToBytes(hexString.toString())); 조금 생각해보십시오. hexToBytes(iv)

+0

포인트 1에 관해서는 내가 몇 가지 라이브러리를 사용하여 동일한 16 진수 코드를 얻지 못하는 것이 었습니다. 이유는 정상적으로했지만 라이브러리를 사용하게되면 원하는 암호화 된 결과를 얻을 것이고 포인트 2를 늘리면 라이브러리를 사용할 것입니다. 키 및 iv의 크기 오류 키가 잘못되었습니다.이 키를 사용하여 열려있는 SSL로 생성하고 있습니다. $ openssl enc -aes-256-cbc -k secret -P -md sha1 –

+0

iv와 key를 모두 확인하십시오. 바이트 배열 크기)는 256 비트 (32 바이트)입니다. 그것은 나를 위해 일했습니다. 그냥 아이디어 - 자바 버전/배포판은 무엇을 사용합니까? [Unlimited Strength JCE Policy] (http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html)가 필요하지 않습니까? – gusto2

+0

내 경우에도 작동하지만 문제는 출력이 openSSL의 출력과 일치하지 않는다는 것입니다. openSSL과 Cryptography에 대한 많은 지식이 없기 때문에 어떻게하면 256 비트 iv와 키를 얻을 수 있습니까? –