Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/jsf/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 非对称加密和解密#_C#_Encryption_Encryption Asymmetric - Fatal编程技术网

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