4

JavaでCBC暗号化の256キーAESを実装したい。受信者は 256 ビットのパスフレーズを文字列 'absnfjtyrufjdngjvhfgksdfrtifghkv' として送信し、次の openssl コマンドを使用して完全に機能します。

 echo test | openssl enc  -aes-256-cbc -a -k 'absnfjtyrufjdngjvhfgksdfrtifghkv'

base64 形式での出力は次のとおりです。 U2FsdGVkX1/yA4J8T+i1M3IZS+TO/V29rBJNl2P88oI=

私がそれを解読すると、元の入力文字列が返されます:

 echo U2FsdGVkX1/yA4J8T+i1M3IZS+TO/V29rBJNl2P88oI= | openssl enc -d -aes-256-cbc -a -k 'absnfjtyrufjdngjvhfgksdfrtifghkv'     

私の問題は、Javaで暗号化を機能させ、上記のコマンドで復号化できないことです。パスフレーズを使用してキーを生成する必要があることはわかっています。以下は、IV がランダムに生成され、キーがパスフレーズとランダムなソルトを使用して生成される私のコードの例です。

byte[] input = "test".getBytes();
String passphrase = "absnfjtyrufjdngjvhfgksdfrtifghkv";
int saltLength = 8; 

SecureRandom random = new SecureRandom();

//randomly generate salt
byte[] salt = new byte[saltLength];
random.nextBytes(salt);

// generating key from passphrase and salt
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
KeySpec spec = new PBEKeySpec(passphrase.toCharArray(), salt, 1024, 256);
SecretKey key = factory.generateSecret(spec);
SecretKey kspec = new SecretKeySpec(key.getEncoded(), "AES");

// randomly generate IV
byte iv[] = new byte[16];
random.nextBytes(iv);
IvParameterSpec ips = new IvParameterSpec(iv);

Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding");
c.init(Cipher.ENCRYPT_MODE, kspec, ips);
byte[] encryptedData = c.doFinal(input);
System.out.println(new String(Base64.encodeBase64(encryptedData)));

私の Java base64 出力は XimWIM+8UewzobFOMfevaw== であり、実行しようとすると次のようになります。

echo XimWIM+8UewzobFOMfevaw= | openssl enc -d -aes-256-cbc -a -k   'absnfjtyrufjdngjvhfgksdfrtifghkv'

「マジック ナンバーが正しくありません」というエラーが表示されます。Java暗号化のどのステップが間違っていますか?

4

1 に答える 1

6

この回答によると、OpenSSL は、Java コードで使用しているものとは異なるキー派生アルゴリズムを使用します。したがって、暗号化に使用されるキーは OpenSSL コマンドと Java プログラムで異なるため、出力は異なり、互換性がありません。

また、OpenSSLのキー派生関数のドキュメントも確認してください。JavaコードがSHA1を使用している間、アルゴリズムでMD5を使用しているようです。それらは同じキーを出力しません。

パスフレーズから導出する代わりに、まったく同じ鍵導出関数を指定するか、鍵を直接指定する必要があります。

最後に、鍵導出関数 (bash と Java を使用して簡単に実装できる) を自分で作成することは避け、セキュリティが懸念される場合は標準に固執します (そうでない場合、わざわざ暗号を使用する必要はありません)。アルゴリズムが壊れる可能性が最も高いです。

于 2013-02-04T21:19:17.110 に答える