5

現在、Java を使用して、C# で作成された Base64 でエンコードされた RSA 暗号化文字列を復号化すると、次のエラーが発生します。

javax.crypto.BadPaddingException: PKCS#1 ブロック タイプ 2 またはゼロ パディングではありません

.NET と Java からの交換の間のセットアップ プロセスは、.NET キー ストアで秘密鍵を作成し、作成された PEM ファイルから抽出し、keytool を使用して秘密鍵で JKS バージョンを作成することによって行われます。Java は、作成済みの JKS をロードし、Base64 文字列をバイト配列にデコードしてから、秘密鍵を使用して復号化します。

暗号化された文字列を作成する C# のコードは次のとおりです。

public string Encrypt(string value) {
    byte[] baIn = null;
    byte[] baRet = null;
    string keyContainerName = "test";

    CspParameters cp = new CspParameters();
    cp.Flags = CspProviderFlags.UseMachineKeyStore;
    cp.KeyContainerName = keyContainerName;
    RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(cp);

    // Convert the input string to a byte array 
    baIn = UnicodeEncoding.Unicode.GetBytes(value);

    // Encrypt
    baRet = rsa.Encrypt(baIn, false);

    // Convert the encrypted byte array to a base64 string
    return Convert.ToBase64String(baRet);
}

入力された文字列を復号化するJavaのコードは次のとおりです。

public void decrypt(String base64String) {
    String keyStorePath = "C:\Key.keystore";
    String storepass = "1234";
    String keypass = "abcd";
    byte[] data = Base64.decode(base64String);
    byte[] cipherData = null;

    keystore = KeyStore.getInstance("JKS");
    keystore.load(new FileInputStream(keyStorePath), storepass.toCharArray());

    RSAPrivateKey privateRSAKey = (RSAPrivateKey) keystore.getKey(alias, keypass.toCharArray());

    Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
    cipher.init(Cipher.DECRYPT_MODE, privateRSAKey);
    cipherData = cipher.doFinal(data);

    System.out.println(new String(cipherData));
}

ステップが欠けている、またはパディングやアイテムを変更する必要がある場所に誰かが気づいていますか? このサイトや他のサイトを何時間も読んできましたが、具体的な解決策は見つかりませんでした。

大変お世話になりました。

ありがとう。-マット

4

4 に答える 4

3

私はまったく同じ問題を抱えていましたが、最終的に解決策を見つけました!

私は頑固に PKCS1Padding を使用していましたが、うまく機能させることができませんでした。

C# 側で"rsa.Encrypt(baIn, false)"を使用し、Java 側で"RSA/NONE/NoPadding"を使用して得た最良の結果は、次のような文字列でした: "☻?o+_>??5?l0Q *???*?R▲???♀7...」の後に復号化された文字列が続きます。ある意味で復号化されましたが、パディングが指定されていないため、データがシフトされます。だから私は bouncycastle で利用可能なすべてのパディングを試しましたが、「ブロックのサイズが正しくありません」や「データハッシュが間違っています」などのエラーが常に発生しました。

そこで、OAEP パディングを試してみることにしました。最終的には、C# 側で「rsa.Encrypt(baIn, true)」を使用し、Java 側で「RSA/NONE/OAEPWithSHA1AndMGF1Padding」を使用して機能させることができました。

それは私にとってはうまくいきました。あなたにとってもうまくいくことを願っています! うまくいかない場合は、正しいキーを使用していることを確認してください。多くの場合、問題はキーに起因しています。

于 2010-05-31T15:00:02.970 に答える
2

Objective-C で .Net と iPhone の間で動作する同様の問題に取り組んでいます。答えは、RSACryptoServiceProvider ドキュメントのこの小さな宝石にあると思います。

アンマネージ CAPI の RSA 実装とは異なり、RSACryptoServiceProvider クラスは、暗号化後と復号化前に、暗号化されたバイト配列の順序を逆にします。デフォルトでは、RSACryptoServiceProvider クラスによって暗号化されたデータは CAPI CryptDecrypt 関数によって暗号化解除できず、CAPI CryptEncrypt メソッドによって暗号化されたデータは RSACryptoServiceProvider クラスによって暗号化解除できません。

詳細については、http: //msdn.microsoft.com/en-us/library/s575f7e2 (v=VS.90).aspx を参照してください。

于 2010-04-12T20:51:35.540 に答える
2

キーを正しく交換したことを確認します。

正しくないキーで復号化しようとすることは、不適切にパディングされたデータを復号化することと区別がつきません。

于 2009-08-20T05:53:04.387 に答える
0

Bouncy Castle 1.48 を使用したときに同じ問題が発生しましたが、キーに関連するものではありませんでした。代わりに、次のシステム プロパティを設定する必要があることがわかりました。

-Dorg.bouncycastle.pkcs1.strict=false
于 2013-07-31T03:01:33.383 に答える