C#使用RSA证书文件加密和解密示例

时间:2021-11-25 16:48:27

修改MSDN上的示例,使之可以通过RSA证书文件加密和解密,中间遇到一个小问题。

Q:执行ExportParameters()方法时,回报CryptographicException:该项不适于在指定状态下使用(Key not valid for use in specified state)。

A:导入带有私钥的证书时,需要使用"X509KeyStorageFlags"参数标记"私钥可导出"。

X509Certificate2 prvcrt = new X509Certificate2(@"X:\path\to\CA.pfx", "***password***", X509KeyStorageFlags.Exportable);

以下为示例程序:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace TeatApp_Crypto
{
using System;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Text; class RSACSPSample
{ static void Main()
{
try
{
//Create a UnicodeEncoder to convert between byte array and string.
UnicodeEncoding ByteConverter = new UnicodeEncoding(); //Create byte arrays to hold original, encrypted, and decrypted data.
byte[] dataToEncrypt = ByteConverter.GetBytes("Data to Encrypt");
byte[] encryptedData;
byte[] decryptedData; X509Certificate2 pubcrt = new X509Certificate2(@"X:\path\to\CA.crt");
RSACryptoServiceProvider pubkey = (RSACryptoServiceProvider)pubcrt.PublicKey.Key;
X509Certificate2 prvcrt = new X509Certificate2(@"X:\path\to\CA.pfx", "***password***", X509KeyStorageFlags.Exportable);
RSACryptoServiceProvider prvkey = (RSACryptoServiceProvider)prvcrt.PrivateKey;
//Create a new instance of RSACryptoServiceProvider to generate
//public and private key data.
//using (RSACryptoServiceProvider RSA = new RSACryptoServiceProvider())
//{
//Console.WriteLine(RSA.ToXmlString(false));
//Pass the data to ENCRYPT, the public key information
//(using RSACryptoServiceProvider.ExportParameters(false),
//and a boolean flag specifying no OAEP padding.
encryptedData = RSAEncrypt(dataToEncrypt, pubkey.ExportParameters(false), false);
Console.WriteLine("Encrypted plaintext: {0}", Convert.ToBase64String(encryptedData)); //Pass the data to DECRYPT, the private key information
//(using RSACryptoServiceProvider.ExportParameters(true),
//and a boolean flag specifying no OAEP padding.
decryptedData = RSADecrypt(encryptedData, prvkey.ExportParameters(true), false); //Display the decrypted plaintext to the console.
Console.WriteLine("Decrypted plaintext: {0}", ByteConverter.GetString(decryptedData));
//}
prvkey.Clear();
pubkey.Clear();
Console.Read();
}
catch (ArgumentNullException)
{
//Catch this exception in case the encryption did
//not succeed.
Console.WriteLine("Encryption failed."); }
} static public byte[] RSAEncrypt(byte[] DataToEncrypt, RSAParameters RSAKeyInfo, bool DoOAEPPadding)
{
try
{
byte[] encryptedData;
//Create a new instance of RSACryptoServiceProvider.
using (RSACryptoServiceProvider RSA = new RSACryptoServiceProvider())
{ //Import the RSA Key information. This only needs
//toinclude the public key information.
RSA.ImportParameters(RSAKeyInfo); //Encrypt the passed byte array and specify OAEP padding.
//OAEP padding is only available on Microsoft Windows XP or
//later.
encryptedData = RSA.Encrypt(DataToEncrypt, DoOAEPPadding);
}
return encryptedData;
}
//Catch and display a CryptographicException
//to the console.
catch (CryptographicException e)
{
Console.WriteLine(e.Message); return null;
} } static public byte[] RSADecrypt(byte[] DataToDecrypt, RSAParameters RSAKeyInfo, bool DoOAEPPadding)
{
try
{
byte[] decryptedData;
//Create a new instance of RSACryptoServiceProvider.
using (RSACryptoServiceProvider RSA = new RSACryptoServiceProvider())
{
//Import the RSA Key information. This needs
//to include the private key information.
RSA.ImportParameters(RSAKeyInfo); //Decrypt the passed byte array and specify OAEP padding.
//OAEP padding is only available on Microsoft Windows XP or
//later.
decryptedData = RSA.Decrypt(DataToDecrypt, DoOAEPPadding);
}
return decryptedData;
}
//Catch and display a CryptographicException
//to the console.
catch (CryptographicException e)
{
Console.WriteLine(e.ToString()); return null;
} }
}
}
C#使用RSA证书文件加密和解密示例
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace TeatApp_Crypto
{
using System;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Text; class RSACSPSample
{ static void Main()
{
try
{
//Create a UnicodeEncoder to convert between byte array and string.
UnicodeEncoding ByteConverter = new UnicodeEncoding(); //Create byte arrays to hold original, encrypted, and decrypted data.
byte[] dataToEncrypt = ByteConverter.GetBytes("Data to Encrypt");
byte[] encryptedData;
byte[] decryptedData; X509Certificate2 pubcrt = new X509Certificate2(@"X:\path\to\CA.crt");
RSACryptoServiceProvider pubkey = (RSACryptoServiceProvider)pubcrt.PublicKey.Key;
X509Certificate2 prvcrt = new X509Certificate2(@"X:\path\to\CA.pfx", "***password***", X509KeyStorageFlags.Exportable);
RSACryptoServiceProvider prvkey = (RSACryptoServiceProvider)prvcrt.PrivateKey;
//Create a new instance of RSACryptoServiceProvider to generate
//public and private key data.
//using (RSACryptoServiceProvider RSA = new RSACryptoServiceProvider())
//{
//Console.WriteLine(RSA.ToXmlString(false));
//Pass the data to ENCRYPT, the public key information
//(using RSACryptoServiceProvider.ExportParameters(false),
//and a boolean flag specifying no OAEP padding.
encryptedData = RSAEncrypt(dataToEncrypt, pubkey.ExportParameters(false), false);
Console.WriteLine("Encrypted plaintext: {0}", Convert.ToBase64String(encryptedData)); //Pass the data to DECRYPT, the private key information
//(using RSACryptoServiceProvider.ExportParameters(true),
//and a boolean flag specifying no OAEP padding.
decryptedData = RSADecrypt(encryptedData, prvkey.ExportParameters(true), false); //Display the decrypted plaintext to the console.
Console.WriteLine("Decrypted plaintext: {0}", ByteConverter.GetString(decryptedData));
//}
prvkey.Clear();
pubkey.Clear();
Console.Read();
}
catch (ArgumentNullException)
{
//Catch this exception in case the encryption did
//not succeed.
Console.WriteLine("Encryption failed."); }
} static public byte[] RSAEncrypt(byte[] DataToEncrypt, RSAParameters RSAKeyInfo, bool DoOAEPPadding)
{
try
{
byte[] encryptedData;
//Create a new instance of RSACryptoServiceProvider.
using (RSACryptoServiceProvider RSA = new RSACryptoServiceProvider())
{ //Import the RSA Key information. This only needs
//toinclude the public key information.
RSA.ImportParameters(RSAKeyInfo); //Encrypt the passed byte array and specify OAEP padding.
//OAEP padding is only available on Microsoft Windows XP or
//later.
encryptedData = RSA.Encrypt(DataToEncrypt, DoOAEPPadding);
}
return encryptedData;
}
//Catch and display a CryptographicException
//to the console.
catch (CryptographicException e)
{
Console.WriteLine(e.Message); return null;
} } static public byte[] RSADecrypt(byte[] DataToDecrypt, RSAParameters RSAKeyInfo, bool DoOAEPPadding)
{
try
{
byte[] decryptedData;
//Create a new instance of RSACryptoServiceProvider.
using (RSACryptoServiceProvider RSA = new RSACryptoServiceProvider())
{
//Import the RSA Key information. This needs
//to include the private key information.
RSA.ImportParameters(RSAKeyInfo); //Decrypt the passed byte array and specify OAEP padding.
//OAEP padding is only available on Microsoft Windows XP or
//later.
decryptedData = RSA.Decrypt(DataToDecrypt, DoOAEPPadding);
}
return decryptedData;
}
//Catch and display a CryptographicException
//to the console.
catch (CryptographicException e)
{
Console.WriteLine(e.ToString()); return null;
} }
}
}
C#使用RSA证书文件加密和解密示例