/// <summary>
        /// 异步加密算法
        /// of specific security profile in the configuration file
        /// </summary>
        /// <param name="data">数据</param>
        /// <param name="profile">配置名</param>
        /// <param name="key">output parameter for generated secret key</param>
        /// <param name="iv">output parameter for generated iv</param>
        /// <param name="signature">out parameters for the digital signature</param>
        /// <returns>stream data</returns>
        public static Stream Encrypt(Stream data, string profile, out byte[] key, out byte[] iv, out byte[] signature)
        {
            var helper = new EncryptionConfigHelper();
            var cm     = helper[profile];


            if (cm.SymmetricAlgorithm)
            {
                throw new Exception("This method id not intended for symmetric  encryption");
            }

            //retireve the sneder and receiver's certification information for encryption
            var    senderCert        = cm.ExtentProperty["SenderCertificate"];
            string sendCertStore     = null;
            string sendCertStoreName = null;
            string password          = null;

            var    receiverCert          = cm.ExtentProperty["ReceiverCertificate"];
            string receiverCertStore     = null;
            string receiverCertStoreName = null;

            var fromFile = cm.ExtentProperty["CertificateFile"] == "true";

            if (!fromFile)
            {
                if (cm.ExtentProperty.ContainsKey("SenderCertificateStore"))
                {
                    sendCertStore = cm.ExtentProperty["SenderCertificateStore"];
                }
                if (cm.ExtentProperty.ContainsKey("SenderCertificateStoreName"))
                {
                    sendCertStoreName = cm.ExtentProperty["SenderCertificateStoreName"];
                }

                if (cm.ExtentProperty.ContainsKey("ReceiverCertificateStore"))
                {
                    receiverCertStore = cm.ExtentProperty["ReceiverCertificateStore"];
                }

                if (cm.ExtentProperty.ContainsKey("ReceiverCertificateStoreName"))
                {
                    receiverCertStoreName = cm.ExtentProperty["ReceiverCertificateStoreName"];
                }
            }
            else
            {
                password = cm.ExtentProperty["SenderCertificatePassword"];
            }

            //obtain the X509 certificate object for the sender and receiver
            var senderCertificate   = fromFile ? Certificate.LoadCertificateByFile(senderCert, password) : Certificate.SearchCertificateBySubjectName(senderCert, sendCertStore, sendCertStoreName);
            var receiverCertificate = fromFile ? Certificate.LoadCertificateByFile(receiverCert, null) : Certificate.SearchCertificateBySubjectName(receiverCert, receiverCertStore, receiverCertStoreName);


            var symmProvider = cm.AlgorithmProvider.CreateInstance <SymmetricAlgorithm>();

            ICryptoTransform encryptor = symmProvider.CreateEncryptor();

            var encStream = new CryptoStream(data, encryptor, CryptoStreamMode.Read);
            var encrypted = new MemoryStream();
            var buffer    = new byte[1024];
            int count;

            while ((count = encStream.Read(buffer, 0, 1024)) > 0)
            {
                encrypted.Write(buffer, 0, count);
            }
            //encrypt the screte key, iv key using receiver's public key
            //that are used to decrypt the data
            var provider = (RSACryptoServiceProvider)receiverCertificate.PublicKey.Key;

            key = provider.Encrypt(symmProvider.Key, false);
            iv  = provider.Encrypt(symmProvider.IV, false);

            //sign the data with sender's private key
            var provider2 = (RSACryptoServiceProvider)senderCertificate.PrivateKey;

            signature          = provider2.SignData(encrypted.ToArray(), new SHA1CryptoServiceProvider());
            encrypted.Position = 0;
            return(encrypted);
        }
        /// <summary>
        /// decrypt the stream data asymmetrically using the security profile
        /// information stored in the configuration file
        /// </summary>
        /// <param name="data">encrypted stream data</param>
        /// <param name="profile">security profile name</param>
        /// <param name="key">generated key</param>
        /// <param name="iv">generated iv</param>
        /// <param name="signature">generated signature</param>
        /// <returns>decrypted stream</returns>
        public static Stream Decrypt(Stream data, string profile, byte[] key, byte[] iv, byte[] signature)
        {
            var helper = new EncryptionConfigHelper();
            var cm     = helper[profile];


            if (cm.SymmetricAlgorithm)
            {
                throw new Exception("This method id not intended for symmetric  encryption");
            }


            //retireve the sneder and receiver's certification information for encryption
            var    senderCert            = cm.ExtentProperty["SenderCertificate"];
            string sendCertStore         = null;
            string sendCertStoreName     = null;
            string password              = null;
            var    receiverCert          = cm.ExtentProperty["ReceiverCertificate"];
            string receiverCertStore     = null;
            string receiverCertStoreName = null;

            var fromFile = cm.ExtentProperty["CertificateFile"] == "true";

            if (!fromFile)
            {
                if (cm.ExtentProperty.ContainsKey("SenderCertificateStore"))
                {
                    sendCertStore = cm.ExtentProperty["SenderCertificateStore"];
                }
                if (cm.ExtentProperty.ContainsKey("SenderCertificateStoreName"))
                {
                    sendCertStoreName = cm.ExtentProperty["SenderCertificateStoreName"];
                }

                if (cm.ExtentProperty.ContainsKey("ReceiverCertificateStore"))
                {
                    receiverCertStore = cm.ExtentProperty["ReceiverCertificateStore"];
                }

                if (cm.ExtentProperty.ContainsKey("ReceiverCertificateStoreName"))
                {
                    receiverCertStoreName = cm.ExtentProperty["ReceiverCertificateStoreName"];
                }
            }
            else
            {
                password = cm.ExtentProperty["SenderCertificatePassword"];
            }
            //obtain the X509 certificate object for the sender and receiver
            var senderCertificate   = fromFile ? Certificate.LoadCertificateByFile(senderCert, password) : Certificate.SearchCertificateBySubjectName(senderCert, sendCertStore, sendCertStoreName);
            var receiverCertificate = fromFile ? Certificate.LoadCertificateByFile(receiverCert, null) : Certificate.SearchCertificateBySubjectName(receiverCert, receiverCertStore, receiverCertStoreName);

            string senderPrivateKey  = senderCertificate.GetKeyAlgorithmParametersString();
            string receiverPublicKey = receiverCertificate.GetPublicKeyString();

            if (string.IsNullOrEmpty(senderPrivateKey) || string.IsNullOrEmpty(receiverPublicKey))
            {
                throw new Exception("用于签名的私有Key或公有Key为空。");
            }

            //import the public key information to verify the data
            var provider = (RSACryptoServiceProvider)receiverCertificate.PublicKey.Key;

            var ms     = new MemoryStream();
            var buffer = new Byte[1024];
            int count;

            while ((count = data.Read(buffer, 0, buffer.Length)) > 0)
            {
                ms.Write(buffer, 0, count);
            }

            var encryptedData = ms.ToArray();
            //data.Position = 0 ;
            //data.Read(encryptedData,0,encryptedData.Length);
            //verify if the data has been tempered with
            var v = provider.VerifyData(encryptedData, new SHA1CryptoServiceProvider(), signature);

            if (v == false)
            {
                throw new CryptographicException();
            }
            //import the private key information to decrypt data
            var provider2 = (RSACryptoServiceProvider)senderCertificate.PrivateKey;
            //decrypt the secret key and iv
            var decryptedkey = provider2.Decrypt(key, false);
            var decryptediv  = provider2.Decrypt(iv, false);

            var symmProvider = SymmetricAlgorithm.Create(cm.AlgorithmProvider);

            symmProvider.Key = decryptedkey;
            symmProvider.IV  = decryptediv;
            var decryptor = symmProvider.CreateDecryptor();

            ms.Position = 0;
            //decrypt the stream
            var decStream = new CryptoStream(ms, decryptor, CryptoStreamMode.Read);
            var decrypted = new MemoryStream();

            while ((count = decStream.Read(buffer, 0, buffer.Length)) != 0)
            {
                decrypted.Write(buffer, 0, count);
            }
            decrypted.Position = 0;
            return(decrypted);
        }