4

我已经实现了这段代码,用于使用公钥加密消息并使用私钥解密..现在我需要使用私钥更改它加密并使用公钥解密。我应该在以下代码中更改什么,我是初学者。请帮助。

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();
                }
            }
        }
    }
4

0 回答 0