C# - 使用RSA加密和解密数据

时间:2013-04-28 10:13:56

标签: c# encryption cryptography

我在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。我该怎么解决这个问题呢?

更新

我解决了一个问题。从字节数组转换为字符串时,我不得不使用Encoding.UTF8.GetString(EncryptedBytes)。现在的问题是,decrypt方法给了我另一个加密异常(他要解密的数据超过了这个128字节模数的最大值)。

有谁知道为什么会这样,以及如何解决?

2 个答案:

答案 0 :(得分:3)

您可以使用base64 Format来替换函数

来转换变量(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;
}

答案 1 :(得分:2)

不要将加密数据视为字符串。加密算法处理二进制数据,并生成二进制数据,不能将其解释为字符串。认为UTF-8或任何其他编码能够将任何给定的二进制数据块解释为有效字符串是天真的。

在您的情况下,如果您需要将加密数据输出到控制台以进行调试,请继续byte[]并将其转储为十六进制,如下所示:

for (int i = 0; i < data.Length; i++)
{
    Console.Write(data[i].ToString("X2"));
    Console.Write(" ");
    if ((i+1) % 16 == 0) Console.WriteLine();
}