C# 非对称加密和解密#
我已经实现了用公钥加密和用私钥解密消息的代码。现在我需要将其更改为用私钥加密和用公钥解密。我应该在下面的代码中更改什么,我是初学者。请帮助C# 非对称加密和解密#,c#,encryption,encryption-asymmetric,C#,Encryption,Encryption Asymmetric,我已经实现了用公钥加密和用私钥解密消息的代码。现在我需要将其更改为用私钥加密和用公钥解密。我应该在下面的代码中更改什么,我是初学者。请帮助 public static string Encrypt(string plainText, X509Certificate2 certificate) { if (string.IsNullOrEmpty(plainText)) throw new ArgumentNullException("plainTe
public static string Encrypt(string plainText, X509Certificate2 certificate)
{
if (string.IsNullOrEmpty(plainText))
throw new ArgumentNullException("plainText");
using (var aesManaged = new AesManaged())
{
aesManaged.KeySize = 256;
aesManaged.BlockSize = 128;
aesManaged.Mode = CipherMode.CBC;
// Create the streams used for encryption.
using (var memoryStream = new MemoryStream())
{
// Generate a Symmetric Key used to actually encrypt the data
RSAPKCS1KeyExchangeFormatter keyFormatter = new RSAPKCS1KeyExchangeFormatter((RSACryptoServiceProvider)certificate.PublicKey.Key);
byte[] keyEncrypted = keyFormatter.CreateKeyExchange(aesManaged.Key, aesManaged.GetType());
//byte[] LenSalt = new byte[_saltSize];
// Create byte arrays to contain
// the length values of the key and IV.
byte[] LenK = new byte[_keyBytes];
byte[] LenIV = new byte[_keyBytes];
// Salt genration :
// default iteration count is 1000 in .NET (this is the same as when using Constructor(string password, int salt))
//using (var keyDerivationFunction = new Rfc2898DeriveBytes(keyEncrypted, LenSalt, _iterations))
//{
// LenSalt = keyDerivationFunction.Salt;
//}
int lKey = keyEncrypted.Length;
LenK = BitConverter.GetBytes(lKey);
int lIV = aesManaged.IV.Length;
LenIV = BitConverter.GetBytes(lIV);
// Write the following to the Stream
// for the encrypted file (outFs):
// - length of the key
// - length of the IV
// - encrypted key
// - the IV
// - the encrypted cipher content
memoryStream.Write(LenK, 0, 4);
memoryStream.Write(LenIV, 0, 4);
//memoryStream.Write(LenSalt, 0, 4);
memoryStream.Write(keyEncrypted, 0, lKey);
memoryStream.Write(aesManaged.IV, 0, lIV);
//memoryStream.Write(LenSalt, 0, _saltSize);
//using (var encryptor = aesManaged.CreateEncryptor(aesManaged.Key, aesManaged.IV))
using (var encryptor = aesManaged.CreateEncryptor())
using (var memoryStreamEnc = new MemoryStream())
{
using (var cryptoStream = new CryptoStream(memoryStreamEnc, encryptor, CryptoStreamMode.Write))
using (var streamWriter = new StreamWriter(cryptoStream))
{
// Send the data through the StreamWriter, through the CryptoStream, to the underlying MemoryStream
streamWriter.Write(plainText);
}
memoryStream.Write(memoryStreamEnc.ToArray(), 0, memoryStreamEnc.ToArray().Length);
}
return Convert.ToBase64String(memoryStream.ToArray());
}
}
}
/// <summary>
/// Decrypts the ciphertext using the public key.
/// </summary>
/// <param name="ciphertext">The ciphertext to decrypt.</param>
/// <param name="certificate">The RSA certificate (need access to Private Key for decryption to work).</param>
/// <returns>The decrypted text.</returns>
public static string Decrypt(string ciphertext, X509Certificate2 certificate)
{
string outstring = string.Empty;
if (string.IsNullOrEmpty(ciphertext))
throw new ArgumentNullException("cipherText");
if (!certificate.HasPrivateKey)
throw new ApplicationException("The private key is not accessible. Decryption is not supported.");
var allTheBytes = Convert.FromBase64String(ciphertext);
//using (var keyDerivationFunction = new Rfc2898DeriveBytes(UTF8Encoding.UTF8.GetString(symmetricKey), saltBytes))
using (var aesManaged = new AesManaged())
{
aesManaged.KeySize = 256;
aesManaged.BlockSize = 128;
aesManaged.Mode = CipherMode.CBC;
// Create byte arrays to get the length of
// the encrypted key and IV.
// These values were stored as 4 bytes each
// at the beginning of the encrypted package.
byte[] LenK = new byte[_keyBytes];
byte[] LenIV = new byte[_keyBytes];
using (MemoryStream InStr = new MemoryStream(allTheBytes))
{
InStr.Seek(0, SeekOrigin.Begin);
InStr.Read(LenK, 0, _keyBytes - 1);
InStr.Seek(_keyBytes, SeekOrigin.Begin);
InStr.Read(LenIV, 0, _keyBytes - 1);
// Convert the lengths to integer values.
int lenK = BitConverter.ToInt32(LenK, 0);
int lenIV = BitConverter.ToInt32(LenIV, 0);
// Determine the start postition of
// the ciphter text (startC)
// and its length(lenC).
int startC = lenK + lenIV + 8;
int lenC = (int)InStr.Length - startC;
// Create the byte arrays for
// the encrypted AesManaged key,
// the IV, and the cipher text.
byte[] KeyEncrypted = new byte[lenK];
byte[] IV = new byte[lenIV];
// Extract the salt, key and IV
// starting from index 8
// after the length values.
InStr.Seek(8, SeekOrigin.Begin);
InStr.Read(KeyEncrypted, 0, lenK);
InStr.Seek(8 + lenK, SeekOrigin.Begin);
InStr.Read(IV, 0, lenIV);
byte[] KeyDecrypted = ((RSACryptoServiceProvider)certificate.PrivateKey).Decrypt(KeyEncrypted, false);
byte[] CipherTextBytes = new byte[lenC];
InStr.Seek(startC, SeekOrigin.Begin);
InStr.Read(CipherTextBytes, 0, lenC);
using (var decryptor = aesManaged.CreateDecryptor(KeyDecrypted, IV))
using (var memoryStream = new MemoryStream(CipherTextBytes))
using (var cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read))
using (var streamReader = new StreamReader(cryptoStream))
{
// Return the decrypted bytes from the decrypting stream.
return streamReader.ReadToEnd();
}
}
}
}
公共静态字符串加密(字符串明文,X509Certificate2证书)
{
if(string.IsNullOrEmpty(纯文本))
抛出新的ArgumentNullException(“明文”);
使用(var aesManaged=new aesManaged())
{
aesManaged.KeySize=256;
AES.BlockSize=128;
aes.Mode=CipherMode.CBC;
//创建用于加密的流。
使用(var memoryStream=new memoryStream())
{
//生成用于实际加密数据的对称密钥
RSAPKCS1KeyExchangeFormatter keyFormatter=新的RSAPKCS1KeyExchangeFormatter((rsacryptserviceprovider)certificate.PublicKey.Key);
byte[]keyEncrypted=keyFormatter.CreateKeyExchange(aesManaged.Key,aesManaged.GetType());
//字节[]LenSalt=新字节[_saltSize];
//创建要包含的字节数组
//键和IV的长度值。
字节[]LenK=新字节[_keyBytes];
字节[]LenIV=新字节[_keyBytes];
//盐的生成:
//NET中的默认迭代计数为1000(这与使用构造函数时相同(字符串密码,int salt))
//使用(var keydrivationfunction=new Rfc2898DeriveBytes(keycencrypted,LenSalt,_迭代))
//{
//LenSalt=keydrivationfunction.Salt;
//}
int lKey=密钥加密的.Length;
LenK=位转换器.GetBytes(lKey);
int-lIV=1.IV.长度;
LenIV=位转换器.GetBytes(lIV);
//将以下内容写入流
//对于加密文件(outps):
//-钥匙的长度
//-静脉注射的长度
//-加密密钥
//-第四
//-加密的密码内容
内存流写入(LenK,0,4);
memoryStream.Write(LenIV,0,4);
//memoryStream.Write(LenSalt,0,4);
memoryStream.Write(密钥加密,0,lKey);
memoryStream.Write(0.IV,0,lIV);
//memoryStream.Write(LenSalt,0,_saltSize);
//使用(var encryptor=aesManaged.CreateEncryptor(aesManaged.Key,aesManaged.IV))
使用(var encryptor=aesManaged.CreateEncryptor())
使用(var MemoryStream=new MemoryStream())
{
使用(var cryptoStream=新加密流(memoryStreamEnc、encryptor、CryptoStreamMode.Write))
使用(var streamWriter=newstreamwriter(cryptoStream))
{
//通过StreamWriter、CryptoStream将数据发送到底层MemoryStream
streamWriter.Write(纯文本);
}
memoryStream.Write(memoryStream.ToArray(),0,memoryStream.ToArray().Length);
}
返回Convert.tobase64字符串(memoryStream.ToArray());
}
}
}
///
///使用公钥解密密文。
///
///要解密的密文。
///RSA证书(需要访问私钥才能解密)。
///解密的文本。
公共静态字符串解密(字符串密文,X509Certificate2证书)
{
string outstring=string.Empty;
if(string.IsNullOrEmpty(密文))
抛出新的ArgumentNullException(“密文”);
如果(!certificate.HasPrivateKey)
抛出新的ApplicationException(“私钥不可访问。不支持解密”);
var allTheBytes=Convert.fromBase64字符串(密文);
//使用(var keydrivationfunction=new Rfc2898DeriveBytes(UTF8Encoding.UTF8.GetString(symmetricKey),saltBytes))
使用(var aesManaged=new aesManaged())
{
aesManaged.KeySize=256;
AES.BlockSize=128;
aes.Mode=CipherMode.CBC;
//创建字节数组以获取
//加密密钥和IV。
//这些值分别存储为4个字节
//在加密包的开头。
字节[]LenK=新字节[_keyBytes];
字节[]LenIV=新字节[_keyBytes];
使用(内存流指令=新内存流(所有字节))
{
指令寻道(0,SeekOrigin.Begin);
指令读取(LenK,0,_keyBytes-1);
InStr.Seek(_keyBytes,SeekOrigin.Begin);
指令读取(LenIV,0,_keyBytes-1);
//将长度转换为整数值。
int lenK=BitConverter.ToInt32(lenK,0);
int lenIV=位转换器.ToInt32(lenIV,0);
//确定设备的起始位置
//密码文本(startC)
//以及它的长度(lenC)。
int startC=lenK+lenIV+8;
int lenC=(int)仪器长度-开始;
//为其创建字节数组
//加密的托管密钥,
//IV和密码文本。
字节[]密钥加密=新字节[lenK];
字节[]IV=新字节[lenIV];
//取出盐、钥匙和IV
//从索引8开始
//在长度值之后。
指令寻道(8,见科里金开始);
指令读取(密钥加密,0,lenK);
仪表寻道(8+l