2017-11-27 17 views
0

こんにちは、OpenSSLコマンドを使用してメッセージを暗号化および復号化しています。今私はこのコマンドをJavaコードで変換する必要があります。私はWeb上で提供されたさまざまなソリューションを試しましたが、コードのどれもが結果と一致しません。ここでOpenSSL AES/CBC 256コマンドの出力がjavaコードの出力と一致しません

はコメントで私の過小と私のopensslコマンドです:

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>" 

これは私がJavaでやっていることです:

注:スタックオーバーフローから、このコードはマイナーチェンジで答えを受け入れた私は、他のコードも試してみましたが、ここでは言及できません。それはとても例外を生産している)

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

がある他の問題であってもよいが、最初に同じパラメータを持っていることができますこと - あなたが唯一の16鍵のバイトを渡している、あなたは効果的にOpenSSLが 'AES-256-cbc'で使用されるAES-128を行っています。次へ - なぜあなたは16進/ストリング変換を自分でやっていますか? ( – gusto2

+0

[Java AES 128はopensslとは異なる暗号化](http://stackoverflow.com/q/21086103/608639)、[Java OpenSSL AES CBC暗号化と同等](http://stackoverflow.com/q/32508961/608639)、[openssl aes-128-cbcでエンコードされた文字列をjavaを使用してデコードする方法は?](http://stackoverflow.com/q/31947256/608639)、[Javaを使用してopenssl aes-256-提供されたキーとiv](http://stackoverflow.com/q/15594518/608639)などを使用するcbc – jww

+0

通常['EVP_BytesToKey'](http://wiki.openssl.org/index.php/Manual:EVP_BytesToKey (3))も問題の1つです。[JavaのC++暗号化](http://stackoverflow.com/q/12920740/608639)、[JavaでOpenSSLで生成された鍵の使い方](http:// (OpenSSLコマンドと互換性のあるキー機能へのパスワード?)([Java OpenSSL暗号化/復号化キー生成](http://stackoverflow.com/q/34502705/608639) http://stackoverflow.com/q/9488919)、[ファイルを解読する方法AESを使用してopensslコマンドで暗号化されたJava?](http://stackoverflow.com/q/11783062)など – jww

答えて

0

あなたは

はのは、あなたがやりたいことは、あなたがいくつかのミス(WTFモーメントを)持っているあなたのコード内

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

であると仮定してみましょう、あなたのコード内のいくつかのミスを持っています。私は基本的にあなたのためにそれらを修正しませんが。

  1. を私はいくつかの通常のライブラリを使用するためにアドバイスしたい(例えばコモンズ・コーデックを、...)の六角から/デコードをエンコードするために、しかしこれまでのところ、それが働いているようです

  2. あなたは16バイト(128ビット)を使用しており、効果的にAES-128を実行しています。キーとivビットを持つAES-256(32バイト)を使用する必要があります。両方とも16バイトにカットしているので、opensslで使用されている値とは異なります。

  3. メインブレークポイント:IvParameterSpec ivSpec = new IvParameterSpec(hexToBytes(hexString.toString()));これは少し考えてください。 hexToBytes(iv)

+0

ポイント1については、なぜ私はそれを正常にしたのですが、ライブラリを使用するいくつかのライブラリを使用して同じ16進コードを取得していなかったことを心配しています。キーのサイズとivエラーが発生しています無効なキーとこのキー私はコマンドを使用してオープンSSLで生成しています$ openssl enc -aes-256-cbc -kシークレット-P -md sha1 –

+0

ivとkeyバイト配列サイズ)は256ビット(32バイト)です。それは私のために働いた。ちょっとしたアイデア - どのJavaバージョン/ディストリビューションを使用しますか? [Unlimited Strength JCE Policy](http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html)は必要ありませんか? – gusto2

+0

それは私のケースでも働いていますが、問題はその出力がopenSSLの出力と一致していないことです。私はopenSSLと暗号の知識があまりないので、私はどのように私は256ビットivとキー感謝を得ることができますか? –

関連する問題