4

私はC#で次のコードを持っています:

メインクラス

X509Certificate2 cert = new X509Certificate2("C:/test.pfx", "hello", X509KeyStorageFlags.Exportable | X509KeyStorageFlags.PersistKeySet);

            Encryption enc = new Encryption();
            string encrypted = enc.Encrypt("hello there", cert);
            string decrypted = enc.Decrypt(encrypted, cert);
            Console.WriteLine("Encrypted Text: " + encrypted);
            Console.WriteLine("Decrypted Text: " + decrypted);

暗号化クラス

public string Encrypt(string plainText, X509Certificate2 cert)
{
    RSACryptoServiceProvider publicKey = (RSACryptoServiceProvider)cert.PublicKey.Key;
    byte[] plainBytes = Encoding.UTF8.GetBytes(plainText);
    byte[] encryptedBytes = publicKey.Encrypt(plainBytes, false);
    string encryptedText = encryptedBytes.ToString();
    return encryptedText;
}

public string Decrypt(string encryptedText, X509Certificate2 cert)
{
    RSACryptoServiceProvider privateKey = (RSACryptoServiceProvider)cert.PrivateKey;
    byte[] encryptedBytes = Encoding.UTF8.GetBytes(encryptedText);
    byte[] decryptedBytes = privateKey.Decrypt(encryptedBytes, false);
    string decryptedText = decryptedBytes.ToString();
    return decryptedText;
}

ご覧のとおり、メイン クラスで証明書をインポートしています。次に、Encryption クラスのインスタンスを作成しています。次に、暗号化されたテキストを取得するために、プレーンテキストを証明書と共に Encrypt メソッドに渡します。その後、暗号化されたテキストを Decrypt メソッドに渡して、プレーンテキストを取得します。

私の問題は、暗号化されたテキストを出力した結果が System.[]Byte になることです (復号化呼び出しをコメントアウトした場合)。復号化呼び出しをコメントアウトしないと、復号化メソッドで暗号化例外: 不正なデータが発生します。

encryptedBytes 配列が文字列に正しく変換されていないと思います。さらに、RSAEncryptionProvider を正しく形成しているかどうかもわかりません。どうすればこれを解決できますか?

アップデート

1つの問題を解決しました。バイト配列から文字列に変換するときは、Encoding.UTF8.GetString(EncryptedBytes) を使用する必要がありました。ここでの問題は、復号化メソッドが別の暗号化例外を与えていることです (復号化されるデータは、このモジュラスの最大値である 128 バイトを超えています)。

なぜこれが起こっているのか、それを解決する方法を知っている人はいますか?

4

2 に答える 2

4

関数を置き換えることにより、base64形式を使用して変数(encryptedText)パラメーターのタイプを変換できます

public string Encrypt(string plainText, X509Certificate2 cert)
{
    RSACryptoServiceProvider publicKey = (RSACryptoServiceProvider)cert.PublicKey.Key;
    byte[] plainBytes = Encoding.UTF8.GetBytes(plainText);
    byte[] encryptedBytes = publicKey.Encrypt(plainBytes, false);
    string encryptedText = Convert.ToBase64String(encryptedBytes);
    return encryptedText;
}

public string Decrypt(string encryptedText, X509Certificate2 cert)
{
    RSACryptoServiceProvider privateKey = (RSACryptoServiceProvider)cert.PrivateKey;
    byte[] encryptedBytes = Convert.FromBase64String(encryptedText);
    byte[] decryptedBytes = privateKey.Decrypt(encryptedBytes, false);
    string decryptedText = Encoding.UTF8.GetString(decryptedBytes);
    return decryptedText;
}
于 2017-06-26T15:21:21.870 に答える
3

暗号化されたデータを文字列として扱わないでください。暗号化アルゴリズムはバイナリ データに作用し、文字列として解釈できないバイナリ データを生成します。UTF-8 またはその他のエンコーディングが、バイナリ データの任意のチャンクを有効な文字列として解釈できると考えるのは単純です。

あなたの場合、デバッグ目的で暗号化されたデータをコンソールに出力する必要がある場合は、次のbyte[]ように 16 進数でダンプしてください。

for (int i = 0; i < data.Length; i++)
{
    Console.Write(data[i].ToString("X2"));
    Console.Write(" ");
    if ((i+1) % 16 == 0) Console.WriteLine();
}
于 2013-04-28T10:39:28.253 に答える