关于加密:C# – 使用RSA加密和解密数据

C# - Encrypting and Decrypting Data using RSA

我在C中有以下代码:

主类

1
2
3
4
5
6
7
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);

加密类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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;
}

如您所见,在主类中,我正在导入一个证书。然后我创建了一个加密类的实例。然后,我将明文和证书一起传递给encrypt方法,以获取加密的文本。然后,我将加密的文本传递给decrypt方法以取回明文。

我的问题是,打印加密文本的结果是系统。[]字节(如果我注释掉解密调用)。如果我不评论解密调用,我会得到一个加密异常:解密方法中的错误数据。

我想加密字节数组没有正确地转换成字符串。此外,我不确定是否正确地构造了rsaencryptionProvider。我怎么解决这个问题?

更新

我解决了一个问题。当从字节数组转换为字符串时,我必须使用encoding.utf8.getString(encryptedBytes)。现在的问题是,decrypt方法给了我另一个加密异常(要解密的数据超过了这个模块128字节的最大值)。

有人知道为什么会发生这种情况以及如何解决它吗?


可以使用base64格式通过替换函数来转换变量类型(encryptedText)参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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;
}

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

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

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