4

以前、C# で RSACryptoServiceProvider を使用して一部のデータを暗号化しましたが、この暗号化を Android プログラムで複製する必要があります。C# プログラムで得たのと同じ結果を Android プログラムで生成したいと考えています。

公開鍵:

<RSAKeyValue>
    <Modulus>zz4qdc39y1BHyJgVXUkINJSbsUd1ZJPISyE9nNGjqgR+ZO1a4cE3ViVCSZCw+6dBdVMFNjzZPBxl0mT57GIq7rcuoT0scesZgxOftbMasPbxp0BGrh3HTpbBMJdCopgcYV98CZERakb8Pgbb0ne/DiW9Aq0kfTBE02/iEHRNuqMNfo1GFo55m0OKbxVoM6UBb8AITQ6lbdvfCgeIvMzRlVrHCwxUNrrX5cS6gurEfJ8Da+prKQmwWpFCkwDkPWje2W+bTSPUc9l6Ads0UimYE5sGs4Zsfz6Eocz4rJjR+qCiB8qt6HtdyjKo0auqYzyXIjdRv2950flc9tOh5bRlQQ==
    </Modulus>
    <Exponent>AQAB</Exponent>
</RSAKeyValue>

Java 暗号化プログラム:

byte[] modulusBytes = Base64.decode(Modoutput.getBytes("UTF-8"),
        Base64.DEFAULT);
byte[] exponentBytes = Base64.decode(Expoutput.getBytes("UTF-8"),
        Base64.DEFAULT);
BigInteger e = new BigInteger(1, exponentBytes);
BigInteger m = new BigInteger(1, modulusBytes);
RSAPublicKeySpec keySpec = new RSAPublicKeySpec(m, e);
KeyFactory fact = KeyFactory.getInstance("RSA");
PublicKey pubKeyn = fact.generatePublic(keySpec);

Log.i("Publickey", pubKeyn.toString());
Cipher cipher = Cipher.getInstance("RSA/ECB/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE, pubKeyn);
byte[] encryptedByteData = cipher.doFinal(byteData);
String outputEncrypted = Base64.encodeToString(encryptedByteData,
        Base64.NO_WRAP);

Log.i("Encrypteddata", outputEncrypted);

上記のコードを試してみましたが、C# とはまったく異なる出力が得られます。私のコードの何が問題なのか誰か教えてもらえますか? 前もって感謝します。


編集: 要求に応じて、Java で暗号化された出力を複製しようとしている C# コードを次に示します。

public static string EncryptText(string text, int keySize,
        string publicKeyXml) {
    var encrypted = Encrypt(Encoding.UTF8.GetBytes(text), keySize,
            publicKeyXml);
    return Convert.ToBase64String(encrypted);
}

public static byte[] Encrypt(byte[] data, int keySize, string publicKeyXml) {
    if (data == null || data.Length == 0)
        throw new ArgumentException("Data are empty", "data");
    int maxLength = GetMaxDataLength(keySize);
    if (data.Length > maxLength)
        throw new ArgumentException(String.Format(
                "Maximum data length is {0}", maxLength), "data");
    if (!IsKeySizeValid(keySize))
        throw new ArgumentException("Key size is not valid", "keySize");
    if (String.IsNullOrEmpty(publicKeyXml))
        throw new ArgumentException("Key is null or empty", "publicKeyXml");

    using (var provider = new RSACryptoServiceProvider(keySize)) {
        provider.FromXmlString(publicKeyXml);
        return provider.Encrypt(data, _optimalAsymmetricEncryptionPadding);
    }
}
4

1 に答える 1

4

暗号化は、定義上、プレーンテキストに関するすべての情報を隠そうとします。これには、同一のプレーンテキストに関する情報が含まれます。これを行うために、さまざまなパディングモード内である種のランダムを使用します(たとえば、PKCS#1 v1.5互換のパディングまたはRSAのOAEPパディング)。したがって、暗号化の観点から言えば、同じ結果が得られた場合、実装は壊れます。

暗号文が正しいかどうかを確認する方法は、秘密鍵を使用して暗号文を復号化することです。それがあなたが始めた平文になるなら、あなたの実装は正しいです。

[編集]C#コードでOAEP暗号化を使用しているのに対し、JavaはデフォルトでPKCS#1v1.5互換スキームを使用していることに注意してください。"RSA/None/OAEPWithSHA1AndMGF1Padding"またはを使用する必要があります"RSA/ECB/OAEPWithSHA1AndMGF1Padding"。利用できない場合は、弾力がある城のプロバイダーを追加します。

于 2013-03-07T20:09:22.470 に答える