private TKey CreateKeyExchangeInfo(SymmetricAlgorithm keyExchangeAlgorithm)
        {
            if (keyExchangeAlgorithm == null)
            {
                throw ExceptionUtility.ArgumentNull(nameof(keyExchangeAlgorithm));
            }

            var keyExchange           = new TKey();
            var keyExchangeParameters = _publicKey.ExportParameters(false);

            using (var keyExchangeAsym = CreateEphemeralAlgorithm(_publicKey.ProviderType, keyExchangeParameters))
            {
                byte[] encodedKeyExchangeInfo;

                using (var keyExchangeAlg = keyExchangeAsym.CreateKeyExchange(keyExchangeParameters))
                {
                    encodedKeyExchangeInfo = keyExchangeAlg.EncodeKeyExchange(keyExchangeAlgorithm, GostKeyExchangeExportMethod.CryptoProKeyExport);
                }

                var keyExchangeInfo = new Gost_28147_89_KeyExchangeInfo();
                keyExchangeInfo.Decode(encodedKeyExchangeInfo);

                keyExchange.SessionEncryptedKey = keyExchangeInfo;
                keyExchange.TransportParameters = keyExchangeAsym.ExportParameters(false);
            }

            return(keyExchange);
        }
        public override SymmetricAlgorithm DecodePrivateKey(byte[] encodedKeyExchangeData, GostKeyExchangeExportMethod keyExchangeExportMethod)
        {
            if (encodedKeyExchangeData == null)
            {
                throw ExceptionUtility.ArgumentNull(nameof(encodedKeyExchangeData));
            }

            int keyExchangeExportAlgId;

            if (keyExchangeExportMethod == GostKeyExchangeExportMethod.GostKeyExport)
            {
                keyExchangeExportAlgId = Constants.CALG_SIMPLE_EXPORT;
            }
            else if (keyExchangeExportMethod == GostKeyExchangeExportMethod.CryptoProKeyExport)
            {
                keyExchangeExportAlgId = Constants.CALG_PRO_EXPORT;
            }
            else
            {
                throw ExceptionUtility.ArgumentOutOfRange(nameof(keyExchangeExportMethod));
            }

            var providerHandle = CryptoApiHelper.GetProviderHandle(ProviderType);

            var keyExchangeInfo = new Gost_28147_89_KeyExchangeInfo();

            keyExchangeInfo.Decode(encodedKeyExchangeData);

            using (var keyHandle = CryptoApiHelper.DuplicateKey(this.GetSafeHandle()))
            {
                CryptoApiHelper.SetKeyExchangeExportAlgId(ProviderType, keyHandle, keyExchangeExportAlgId);

                var keyExchangeHandle = CryptoApiHelper.ImportKeyExchange(providerHandle, keyExchangeInfo, keyHandle);

                return(new Gost_28147_89_SymmetricAlgorithm(ProviderType, providerHandle, keyExchangeHandle));
            }
        }
        private SymmetricAlgorithm DecodeKeyExchangeInternal(byte[] encodedKeyExchangeData, int keyExchangeExportAlgId)
        {
            var keyExchangeInfo = new Gost_28147_89_KeyExchangeInfo();

            keyExchangeInfo.Decode(encodedKeyExchangeData);

            SafeKeyHandleImpl symKeyHandle;
            SafeKeyHandleImpl keyExchangeHandle = null;

            try
            {
                var importedKeyBytes = CryptoApiHelper.EncodePublicBlob(_keyExchangeParameters, _keySize, _signatureAlgId);
                CryptoApiHelper.ImportCspBlob(importedKeyBytes, _provHandle, _keyHandle, out keyExchangeHandle);
                CryptoApiHelper.SetKeyExchangeExportAlgId(ProviderType, keyExchangeHandle, keyExchangeExportAlgId);

                symKeyHandle = CryptoApiHelper.ImportKeyExchange(_provHandle, keyExchangeInfo, keyExchangeHandle);
            }
            finally
            {
                keyExchangeHandle.TryDispose();
            }

            return(new Gost_28147_89_SymmetricAlgorithm(ProviderType, _provHandle, symKeyHandle));
        }