5

.Net WebService から与えられたソルトとパスワードから Java (Android) で AES キーを生成する必要があります。同じパスワードとソルト (Rfc2898DeriveBytes と AesManaged() を使用) を使用して、.net で生成されたキーと同じキーが必要です。Androidでの私のコードは次のとおりです。

char[] passwordAsCharArray = password.toCharArray();
PBEKeySpec pbeKeySpec = new PBEKeySpec(passwordAsCharArray, salt, 1000, 256); 
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
SecretKeySpec secretKey = new SecretKeySpec(factory.generateSecret(spec).getEncoded(), "AES"); 

.net のコードは次のとおりです。

byte[] keyBytes = Encoding.Unicode.GetBytes(key);
Rfc2898DeriveBytes derivedKey = new Rfc2898DeriveBytes(key, keyBytes);
AesManaged rijndaelCSP = new AesManaged();
rijndaelCSP.BlockSize = 128;
rijndaelCSP.KeySize = 256;
rijndaelCSP.Key = derivedKey.GetBytes(rijndaelCSP.KeySize / 8);
rijndaelCSP.IV = derivedKey.GetBytes(rijndaelCSP.BlockSize / 8);                

ICryptoTransform decryptor = rijndaelCSP.CreateDecryptor();

両方のキーを比較すると、それらは異なります。Androidで.Netと同じキーを生成する方法はありますか? (.net で生成されたキーが正しいことはわかっています)。.Net の反復回数は 1000 回で、salt とパスワードも Android と同じです。


OK、まったく同じキー (バイト配列として) は必要ないことがわかりました。.Netで暗号化されたファイル(Javaで)を復号化するためにこれが必要でした-このキーを使用するとBad Padding Exceptionが発生したため、キーが異なっていて問題が発生したと思いますが、 IV のようなキー - それは私の問題を解決しました。返信ありがとうございます。

4

1 に答える 1

2

Java部分は指定されたソルトを使用するのに対し、.NETコードで「キー」(パスワードである必要があります)をソルトとして使用したようです。さらに、ソルトをデコードするために Unicode 文字セットを指定しましたが、これは奇妙です。ソルトは最初からランダムなオクテット文字列 (== バイト配列) である必要があります。

最初にパスワードとランダムなソルトをバイト配列に変換し、(コンソールまたはデバッガーで) 16 進表現を使用して両方を比較し、それらをそれぞれの PBKDF2 関数の入力パラメーターとして使用することをお勧めします。パスワードには UTF-8 エンコーディングをお勧めします。

暗号化では常にすべてのパラメーターを指定します。反復回数など、デフォルトを使用しないようにしてください。入力が 1 ビットずれている場合、出力は完全に正しくなく、どのパラメーターが原因であるかを特定する方法はありません。

Java と .NET PBKDF2 の「プリミティブ」は両方のプラットフォームで同一のようです。インターネット上で動作するコードが公開されています。

于 2013-01-16T21:06:48.387 に答える