using GostCryptography.Asn1.Gost.Gost_28147_89; using GostCryptography.Asn1.Gost.Gost_R3410; using GostCryptography.Base; using GostCryptography.Gost_28147_89; using GostCryptography.Properties; using System; using System.Security.Cryptography; namespace GostCryptography.Gost_R3410 { /// /// Базовый класс для реализации шифрования общего секретного ключа по ГОСТ Р 34.10 /// /// Информация о ключе цифровой подписи ГОСТ Р 34.10 /// Параметры ключа цифровой подписи ГОСТ Р 34.10 /// Алгоритм общего секретного ключа ГОСТ Р 34.10 public abstract class Gost_R3410_KeyExchangeFormatter : GostKeyExchangeFormatter where TKey : Gost_R3410_KeyExchange, new() where TKeyParams : Gost_R3410_KeyExchangeParams where TKeyAlgorithm : Gost_R3410_KeyExchangeAlgorithm { /// /// Конструктор /// protected Gost_R3410_KeyExchangeFormatter() { } /// /// Конструктор /// /// Открытый ключ для шифрации общего секретного ключа /// /// protected Gost_R3410_KeyExchangeFormatter(AsymmetricAlgorithm publicKey) { SetKey(publicKey); } private Gost_R3410_AsymmetricAlgorithmBase _publicKey; /// public override string Parameters => null; /// public override void SetKey(AsymmetricAlgorithm publicKey) { if (publicKey == null) { throw ExceptionUtility.ArgumentNull(nameof(publicKey)); } if (!(publicKey is Gost_R3410_AsymmetricAlgorithmBase gostPublicKey)) { throw ExceptionUtility.ArgumentOutOfRange(nameof(publicKey), Resources.ShouldSupportGost3410); } _publicKey = gostPublicKey; } /// public override byte[] CreateKeyExchange(byte[] keyExchangeData) { if (keyExchangeData == null) { throw ExceptionUtility.ArgumentNull(nameof(keyExchangeData)); } using (var keyExchangeAlgorithm = new Gost_28147_89_SymmetricAlgorithm(_publicKey.ProviderType)) { keyExchangeAlgorithm.Key = keyExchangeData; return CreateKeyExchangeData(keyExchangeAlgorithm); } } /// public override byte[] CreateKeyExchange(byte[] keyExchangeData, Type keyExchangeAlgorithmType) { if (keyExchangeData == null) { throw ExceptionUtility.ArgumentNull(nameof(keyExchangeData)); } if (keyExchangeAlgorithmType == null) { throw ExceptionUtility.ArgumentNull(nameof(keyExchangeAlgorithmType)); } if (!typeof(GostSymmetricAlgorithm).IsAssignableFrom(keyExchangeAlgorithmType)) { throw ExceptionUtility.ArgumentOutOfRange(nameof(keyExchangeAlgorithmType)); } GostSymmetricAlgorithm keyExchangeAlgorithm; if (_publicKey != null) { var constructorInfo = keyExchangeAlgorithmType.GetConstructor(new[] { typeof(ProviderType) }); keyExchangeAlgorithm = (GostSymmetricAlgorithm)constructorInfo.Invoke(new object[] { _publicKey.ProviderType }); } else { keyExchangeAlgorithm = (GostSymmetricAlgorithm)Activator.CreateInstance(keyExchangeAlgorithmType); } using (keyExchangeAlgorithm) { keyExchangeAlgorithm.Key = keyExchangeData; return CreateKeyExchangeData(keyExchangeAlgorithm); } } /// public override byte[] CreateKeyExchangeData(SymmetricAlgorithm keyExchangeAlgorithm) { if (keyExchangeAlgorithm == null) { throw ExceptionUtility.ArgumentNull(nameof(keyExchangeAlgorithm)); } var keyExchangeInfo = CreateKeyExchangeInfo(keyExchangeAlgorithm); return keyExchangeInfo.Encode(); } 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; } /// /// Создает экземпляр алгоритма шифрования общего секретного ключа /// protected abstract Gost_R3410_EphemeralAsymmetricAlgorithm CreateEphemeralAlgorithm(ProviderType providerType, TKeyParams keyExchangeParameters); } }