Files
hcs/Hcs.Client/GostCryptography/Gost_R3410/Gost_R3410_KeyExchangeFormatter.cs
HOME-LAPTOP\kshkulev 33ab055b43 Add project
Basic formatting applied. Unnecessary comments have been removed. Suspicious code is covered by TODO.
2025-08-12 11:21:10 +09:00

163 lines
6.3 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
{
/// <summary>
/// Базовый класс для реализации шифрования общего секретного ключа по ГОСТ Р 34.10
/// </summary>
/// <typeparam name="TKey">Информация о ключе цифровой подписи ГОСТ Р 34.10</typeparam>
/// <typeparam name="TKeyParams">Параметры ключа цифровой подписи ГОСТ Р 34.10</typeparam>
/// <typeparam name="TKeyAlgorithm">Алгоритм общего секретного ключа ГОСТ Р 34.10</typeparam>
public abstract class Gost_R3410_KeyExchangeFormatter<TKey, TKeyParams, TKeyAlgorithm> : GostKeyExchangeFormatter
where TKey : Gost_R3410_KeyExchange, new()
where TKeyParams : Gost_R3410_KeyExchangeParams
where TKeyAlgorithm : Gost_R3410_KeyExchangeAlgorithm
{
/// <summary>
/// Конструктор
/// </summary>
protected Gost_R3410_KeyExchangeFormatter()
{
}
/// <summary>
/// Конструктор
/// </summary>
/// <param name="publicKey">Открытый ключ для шифрации общего секретного ключа</param>
/// <exception cref="ArgumentOutOfRangeException"></exception>
/// <exception cref="ArgumentNullException"></exception>
protected Gost_R3410_KeyExchangeFormatter(AsymmetricAlgorithm publicKey)
{
SetKey(publicKey);
}
private Gost_R3410_AsymmetricAlgorithmBase<TKeyParams, TKeyAlgorithm> _publicKey;
/// <inheritdoc />
public override string Parameters => null;
/// <inheritdoc />
public override void SetKey(AsymmetricAlgorithm publicKey)
{
if (publicKey == null)
{
throw ExceptionUtility.ArgumentNull(nameof(publicKey));
}
if (!(publicKey is Gost_R3410_AsymmetricAlgorithmBase<TKeyParams, TKeyAlgorithm> gostPublicKey))
{
throw ExceptionUtility.ArgumentOutOfRange(nameof(publicKey), Resources.ShouldSupportGost3410);
}
_publicKey = gostPublicKey;
}
/// <inheritdoc />
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);
}
}
/// <inheritdoc />
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);
}
}
/// <inheritdoc />
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;
}
/// <summary>
/// Создает экземпляр алгоритма шифрования общего секретного ключа
/// </summary>
protected abstract Gost_R3410_EphemeralAsymmetricAlgorithm<TKeyParams, TKeyAlgorithm> CreateEphemeralAlgorithm(ProviderType providerType, TKeyParams keyExchangeParameters);
}
}