Add migrated to .NET 8.0 variant of Hcs.Client

This commit is contained in:
2025-09-26 19:48:32 +09:00
parent da127df8f6
commit 6cd2fb82e9
503 changed files with 223796 additions and 0 deletions

View File

@ -0,0 +1,127 @@
using GostCryptography.Asn1.Gost.Gost_R3410_2001;
using GostCryptography.Base;
using GostCryptography.Config;
using GostCryptography.Gost_R3411;
using GostCryptography.Native;
using GostCryptography.Properties;
using System.Security;
using System.Security.Cryptography;
namespace GostCryptography.Gost_R3410
{
/// <summary>
/// Реализация алгоритма ГОСТ Р 34.10-2001
/// </summary>
public sealed class Gost_R3410_2001_AsymmetricAlgorithm : Gost_R3410_AsymmetricAlgorithm<Gost_R3410_2001_KeyExchangeParams, Gost_R3410_2001_KeyExchangeAlgorithm>
{
/// <summary>
/// Размер ключа ГОСТ Р 34.10-2001
/// </summary>
public const int DefaultKeySizeValue = 512;
/// <summary>
/// Наименование алгоритма цифровой подписи ГОСТ Р 34.10-2001
/// </summary>
public const string SignatureAlgorithmValue = "urn:ietf:params:xml:ns:cpxmlsec:algorithms:gostr34102001-gostr3411";
/// <summary>
/// Устаревшее наименование алгоритма цифровой подписи ГОСТ Р 34.10-2001
/// </summary>
public const string ObsoleteSignatureAlgorithmValue = "http://www.w3.org/2001/04/xmldsig-more#gostr34102001-gostr3411";
/// <summary>
/// Наименование алгоритма обмена ключами ГОСТ Р 34.10-2001
/// </summary>
public const string KeyExchangeAlgorithmValue = "urn:ietf:params:xml:ns:cpxmlsec:algorithms:transport-gost2001";
/// <summary>
/// Известные наименования алгоритма цифровой подписи ГОСТ Р 34.10-2001
/// </summary>
public static readonly string[] KnownSignatureAlgorithmNames = { SignatureAlgorithmValue, ObsoleteSignatureAlgorithmValue };
/// <inheritdoc />
[SecuritySafeCritical]
public Gost_R3410_2001_AsymmetricAlgorithm() : this(GostCryptoConfig.ProviderType)
{
}
/// <inheritdoc />
[SecuritySafeCritical]
public Gost_R3410_2001_AsymmetricAlgorithm(ProviderType providerType) : base(providerType, DefaultKeySizeValue)
{
}
/// <inheritdoc />
[SecuritySafeCritical]
public Gost_R3410_2001_AsymmetricAlgorithm(CspParameters providerParameters) : base(providerParameters, DefaultKeySizeValue)
{
}
/// <inheritdoc />
public override string AlgorithmName => SignatureAlgorithmValue;
/// <inheritdoc />
public override string SignatureAlgorithm => SignatureAlgorithmValue;
/// <inheritdoc />
public override string KeyExchangeAlgorithm => KeyExchangeAlgorithmValue;
/// <inheritdoc />
protected override int ExchangeAlgId => Constants.CALG_DH_EL_SF;
/// <inheritdoc />
protected override int SignatureAlgId => Constants.CALG_GR3410EL;
/// <inheritdoc />
protected override Gost_R3410_2001_KeyExchangeParams CreateKeyExchangeParams()
{
return new Gost_R3410_2001_KeyExchangeParams();
}
/// <inheritdoc />
[SecuritySafeCritical]
protected override Gost_R3410_2001_KeyExchangeAlgorithm CreateKeyExchangeAlgorithm(ProviderType providerType, SafeProvHandleImpl provHandle, SafeKeyHandleImpl keyHandle, Gost_R3410_2001_KeyExchangeParams keyExchangeParameters)
{
return new Gost_R3410_2001_KeyExchangeAlgorithm(providerType, provHandle, keyHandle, keyExchangeParameters, KeySizeValue, SignatureAlgId);
}
/// <inheritdoc />
[SecuritySafeCritical]
public override GostHashAlgorithm CreateHashAlgorithm()
{
return new Gost_R3411_94_HashAlgorithm(ProviderType, this.GetSafeHandle<SafeProvHandleImpl>());
}
/// <inheritdoc />
protected override void ValidateHashParameter(byte[] hash)
{
if (hash == null)
{
throw ExceptionUtility.ArgumentNull(nameof(hash));
}
if (hash.Length != Gost_R3411_94_HashAlgorithm.DefaultHashSizeValue / 8)
{
throw ExceptionUtility.ArgumentOutOfRange(nameof(hash), Resources.InvalidHashSize, Gost_R3411_94_HashAlgorithm.DefaultHashSizeValue / 8);
}
}
/// <inheritdoc />
public override GostKeyExchangeFormatter CreateKeyExchangeFormatter()
{
return new Gost_R3410_2001_KeyExchangeFormatter(this);
}
/// <inheritdoc />
public override GostKeyExchangeDeformatter CreateKeyExchangeDeformatter()
{
return new Gost_R3410_2001_KeyExchangeDeformatter(this);
}
/// <inheritdoc />
protected override Gost_R3410_KeyExchangeXmlSerializer<Gost_R3410_2001_KeyExchangeParams> CreateKeyExchangeXmlSerializer()
{
return new Gost_R3410_2001_KeyExchangeXmlSerializer();
}
}
}

View File

@ -0,0 +1,107 @@
using GostCryptography.Asn1.Gost.Gost_R3410_2001;
using GostCryptography.Base;
using GostCryptography.Config;
using GostCryptography.Gost_R3411;
using GostCryptography.Native;
using System.Security;
namespace GostCryptography.Gost_R3410
{
/// <summary>
/// Реализация алгоритма ГОСТ Р 34.10-2001 на основе эфимерного ключа
/// </summary>
public sealed class Gost_R3410_2001_EphemeralAsymmetricAlgorithm : Gost_R3410_EphemeralAsymmetricAlgorithm<Gost_R3410_2001_KeyExchangeParams, Gost_R3410_2001_KeyExchangeAlgorithm>
{
/// <summary>
/// Размер ключа ГОСТ Р 34.10-2001
/// </summary>
public const int DefaultKeySizeValue = 512;
/// <summary>
/// Наименование алгоритма цифровой подписи ГОСТ Р 34.10-2001
/// </summary>
public const string SignatureAlgorithmValue = "urn:ietf:params:xml:ns:cpxmlsec:algorithms:gostr34102001-gostr3411";
/// <summary>
/// Наименование алгоритма обмена ключами ГОСТ Р 34.10-2001
/// </summary>
public const string KeyExchangeAlgorithmValue = "urn:ietf:params:xml:ns:cpxmlsec:algorithms:transport-gost2001";
/// <inheritdoc />
[SecuritySafeCritical]
public Gost_R3410_2001_EphemeralAsymmetricAlgorithm() : this(GostCryptoConfig.ProviderType)
{
}
/// <inheritdoc />
[SecuritySafeCritical]
public Gost_R3410_2001_EphemeralAsymmetricAlgorithm(ProviderType providerType) : base(providerType, DefaultKeySizeValue)
{
}
/// <inheritdoc />
[SecuritySafeCritical]
public Gost_R3410_2001_EphemeralAsymmetricAlgorithm(Gost_R3410_2001_KeyExchangeParams keyParameters) : this(GostCryptoConfig.ProviderType, keyParameters)
{
}
/// <inheritdoc />
[SecuritySafeCritical]
public Gost_R3410_2001_EphemeralAsymmetricAlgorithm(ProviderType providerType, Gost_R3410_2001_KeyExchangeParams keyParameters) : base(providerType, keyParameters, DefaultKeySizeValue)
{
}
/// <inheritdoc />
public override string AlgorithmName => SignatureAlgorithmValue;
/// <inheritdoc />
public override string SignatureAlgorithm => SignatureAlgorithmValue;
/// <inheritdoc />
public override string KeyExchangeAlgorithm => KeyExchangeAlgorithmValue;
/// <inheritdoc />
protected override int ExchangeAlgId => Constants.CALG_DH_EL_EPHEM;
/// <inheritdoc />
protected override int SignatureAlgId => Constants.CALG_GR3410EL;
/// <inheritdoc />
protected override Gost_R3410_2001_KeyExchangeParams CreateKeyExchangeParams()
{
return new Gost_R3410_2001_KeyExchangeParams();
}
/// <inheritdoc />
[SecuritySafeCritical]
protected override Gost_R3410_2001_KeyExchangeAlgorithm CreateKeyExchangeAlgorithm(ProviderType providerType, SafeProvHandleImpl provHandle, SafeKeyHandleImpl keyHandle, Gost_R3410_2001_KeyExchangeParams keyExchangeParameters)
{
return new Gost_R3410_2001_KeyExchangeAlgorithm(providerType, provHandle, keyHandle, keyExchangeParameters, KeySizeValue, SignatureAlgId);
}
/// <inheritdoc />
[SecuritySafeCritical]
public override GostHashAlgorithm CreateHashAlgorithm()
{
return new Gost_R3411_94_HashAlgorithm(ProviderType, this.GetSafeHandle<SafeProvHandleImpl>());
}
/// <inheritdoc />
public override GostKeyExchangeFormatter CreateKeyExchangeFormatter()
{
return new Gost_R3410_2001_KeyExchangeFormatter(this);
}
/// <inheritdoc />
public override GostKeyExchangeDeformatter CreateKeyExchangeDeformatter()
{
return new Gost_R3410_2001_KeyExchangeDeformatter(this);
}
/// <inheritdoc />
protected override Gost_R3410_KeyExchangeXmlSerializer<Gost_R3410_2001_KeyExchangeParams> CreateKeyExchangeXmlSerializer()
{
return new Gost_R3410_2001_KeyExchangeXmlSerializer();
}
}
}

View File

@ -0,0 +1,18 @@
using GostCryptography.Asn1.Gost.Gost_R3410_2001;
using GostCryptography.Base;
using GostCryptography.Native;
using System.Security;
namespace GostCryptography.Gost_R3410
{
/// <inheritdoc />
public sealed class Gost_R3410_2001_KeyExchangeAlgorithm : Gost_R3410_KeyExchangeAlgorithm
{
/// <inheritdoc />
[SecurityCritical]
public Gost_R3410_2001_KeyExchangeAlgorithm(ProviderType providerType, SafeProvHandleImpl provHandle, SafeKeyHandleImpl keyHandle, Gost_R3410_2001_KeyExchangeParams keyExchangeParameters, int keySize, int signatureAlgId)
: base(providerType, provHandle, keyHandle, keyExchangeParameters, keySize, signatureAlgId)
{
}
}
}

View File

@ -0,0 +1,24 @@
using GostCryptography.Asn1.Gost.Gost_R3410_2001;
using System.Security.Cryptography;
namespace GostCryptography.Gost_R3410
{
/// <summary>
/// Реализация дешифрования общего секретного ключа по ГОСТ Р 34.10-2001
/// </summary>
public sealed class Gost_R3410_2001_KeyExchangeDeformatter : Gost_R3410_KeyExchangeDeformatter<
Gost_R3410_2001_KeyExchange,
Gost_R3410_2001_KeyExchangeParams,
Gost_R3410_2001_KeyExchangeAlgorithm>
{
/// <inheritdoc />
public Gost_R3410_2001_KeyExchangeDeformatter()
{
}
/// <inheritdoc />
public Gost_R3410_2001_KeyExchangeDeformatter(AsymmetricAlgorithm privateKey) : base(privateKey)
{
}
}
}

View File

@ -0,0 +1,31 @@
using GostCryptography.Asn1.Gost.Gost_R3410_2001;
using GostCryptography.Base;
using System.Security.Cryptography;
namespace GostCryptography.Gost_R3410
{
/// <summary>
/// Реализация шифрования общего секретного ключа по ГОСТ Р 34.10-2001
/// </summary>
public sealed class Gost_R3410_2001_KeyExchangeFormatter : Gost_R3410_KeyExchangeFormatter<
Gost_R3410_2001_KeyExchange,
Gost_R3410_2001_KeyExchangeParams,
Gost_R3410_2001_KeyExchangeAlgorithm>
{
/// <inheritdoc />
public Gost_R3410_2001_KeyExchangeFormatter()
{
}
/// <inheritdoc />
public Gost_R3410_2001_KeyExchangeFormatter(AsymmetricAlgorithm publicKey) : base(publicKey)
{
}
/// <inheritdoc />
protected override Gost_R3410_EphemeralAsymmetricAlgorithm<Gost_R3410_2001_KeyExchangeParams, Gost_R3410_2001_KeyExchangeAlgorithm> CreateEphemeralAlgorithm(ProviderType providerType, Gost_R3410_2001_KeyExchangeParams keyExchangeParameters)
{
return new Gost_R3410_2001_EphemeralAsymmetricAlgorithm(providerType, keyExchangeParameters);
}
}
}

View File

@ -0,0 +1,20 @@
using GostCryptography.Asn1.Gost.Gost_R3410_2001;
namespace GostCryptography.Gost_R3410
{
/// <summary>
/// XML-сериализатора параметров ключа цифровой подписи ГОСТ Р 34.10-2001
/// </summary>
public sealed class Gost_R3410_2001_KeyExchangeXmlSerializer : Gost_R3410_KeyExchangeXmlSerializer<Gost_R3410_2001_KeyExchangeParams>
{
/// <summary>
/// Имя тега с информацией о параметрах ключа ГОСТ Р 34.10-2001
/// </summary>
public const string KeyValueTag = "GostKeyValue";
/// <inheritdoc />
public Gost_R3410_2001_KeyExchangeXmlSerializer() : base(KeyValueTag)
{
}
}
}

View File

@ -0,0 +1,20 @@
using GostCryptography.Base;
using GostCryptography.Gost_R3411;
namespace GostCryptography.Gost_R3410
{
/// <summary>
/// Информация о свойствах цифровой подписи ГОСТ Р 34.10-2001
/// </summary>
public sealed class Gost_R3410_2001_SignatureDescription : GostSignatureDescription
{
/// <inheritdoc />
public Gost_R3410_2001_SignatureDescription()
{
KeyAlgorithm = typeof(Gost_R3410_2001_AsymmetricAlgorithm).AssemblyQualifiedName;
DigestAlgorithm = typeof(Gost_R3411_94_HashAlgorithm).AssemblyQualifiedName;
FormatterAlgorithm = typeof(GostSignatureFormatter).AssemblyQualifiedName;
DeformatterAlgorithm = typeof(GostSignatureDeformatter).AssemblyQualifiedName;
}
}
}

View File

@ -0,0 +1,122 @@
using GostCryptography.Asn1.Gost.Gost_R3410_2012_256;
using GostCryptography.Base;
using GostCryptography.Config;
using GostCryptography.Gost_R3411;
using GostCryptography.Native;
using GostCryptography.Properties;
using System.Security;
using System.Security.Cryptography;
namespace GostCryptography.Gost_R3410
{
/// <summary>
/// Реализация алгоритма ГОСТ Р 34.10-2012/256
/// </summary>
public sealed class Gost_R3410_2012_256_AsymmetricAlgorithm : Gost_R3410_AsymmetricAlgorithm<Gost_R3410_2012_256_KeyExchangeParams, Gost_R3410_2012_256_KeyExchangeAlgorithm>
{
/// <summary>
/// Размер ключа ГОСТ Р 34.10-2012/256
/// </summary>
public const int DefaultKeySizeValue = 512;
/// <summary>
/// Наименование алгоритма цифровой подписи ГОСТ Р 34.10-2012/256
/// </summary>
public const string SignatureAlgorithmValue = "urn:ietf:params:xml:ns:cpxmlsec:algorithms:gostr34102012-gostr34112012-256";
/// <summary>
/// Наименование алгоритма обмена ключами ГОСТ Р 34.10-2012/256
/// </summary>
public const string KeyExchangeAlgorithmValue = "urn:ietf:params:xml:ns:cpxmlsec:algorithms:transport-gost2012-256";
/// <summary>
/// Известные наименования алгоритма цифровой подписи ГОСТ Р 34.10-2012/256
/// </summary>
public static readonly string[] KnownSignatureAlgorithmNames = { SignatureAlgorithmValue };
/// <inheritdoc />
[SecuritySafeCritical]
public Gost_R3410_2012_256_AsymmetricAlgorithm() : this(GostCryptoConfig.ProviderType_2012_512)
{
}
/// <inheritdoc />
[SecuritySafeCritical]
public Gost_R3410_2012_256_AsymmetricAlgorithm(ProviderType providerType) : base(providerType, DefaultKeySizeValue)
{
}
/// <inheritdoc />
[SecuritySafeCritical]
public Gost_R3410_2012_256_AsymmetricAlgorithm(CspParameters providerParameters) : base(providerParameters, DefaultKeySizeValue)
{
}
/// <inheritdoc />
public override string AlgorithmName => SignatureAlgorithmValue;
/// <inheritdoc />
public override string SignatureAlgorithm => SignatureAlgorithmValue;
/// <inheritdoc />
public override string KeyExchangeAlgorithm => KeyExchangeAlgorithmValue;
/// <inheritdoc />
protected override int ExchangeAlgId => Constants.CALG_DH_GR3410_2012_256_SF;
/// <inheritdoc />
protected override int SignatureAlgId => Constants.CALG_GR3410_2012_256;
/// <inheritdoc />
protected override Gost_R3410_2012_256_KeyExchangeParams CreateKeyExchangeParams()
{
return new Gost_R3410_2012_256_KeyExchangeParams();
}
/// <inheritdoc />
[SecuritySafeCritical]
protected override Gost_R3410_2012_256_KeyExchangeAlgorithm CreateKeyExchangeAlgorithm(ProviderType providerType, SafeProvHandleImpl provHandle, SafeKeyHandleImpl keyHandle, Gost_R3410_2012_256_KeyExchangeParams keyExchangeParameters)
{
return new Gost_R3410_2012_256_KeyExchangeAlgorithm(providerType, provHandle, keyHandle, keyExchangeParameters, KeySizeValue, SignatureAlgId);
}
/// <inheritdoc />
[SecuritySafeCritical]
public override GostHashAlgorithm CreateHashAlgorithm()
{
return new Gost_R3411_2012_256_HashAlgorithm(ProviderType, this.GetSafeHandle<SafeProvHandleImpl>());
}
/// <inheritdoc />
protected override void ValidateHashParameter(byte[] hash)
{
if (hash == null)
{
throw ExceptionUtility.ArgumentNull(nameof(hash));
}
if (hash.Length != Gost_R3411_2012_256_HashAlgorithm.DefaultHashSizeValue / 8)
{
throw ExceptionUtility.ArgumentOutOfRange(nameof(hash), Resources.InvalidHashSize, Gost_R3411_2012_256_HashAlgorithm.DefaultHashSizeValue / 8);
}
}
/// <inheritdoc />
public override GostKeyExchangeFormatter CreateKeyExchangeFormatter()
{
return new Gost_R3410_2012_256_KeyExchangeFormatter(this);
}
/// <inheritdoc />
public override GostKeyExchangeDeformatter CreateKeyExchangeDeformatter()
{
return new Gost_R3410_2012_256_KeyExchangeDeformatter(this);
}
/// <inheritdoc />
protected override Gost_R3410_KeyExchangeXmlSerializer<Gost_R3410_2012_256_KeyExchangeParams> CreateKeyExchangeXmlSerializer()
{
return new Gost_R3410_2012_256_KeyExchangeXmlSerializer();
}
}
}

View File

@ -0,0 +1,107 @@
using GostCryptography.Asn1.Gost.Gost_R3410_2012_256;
using GostCryptography.Base;
using GostCryptography.Config;
using GostCryptography.Gost_R3411;
using GostCryptography.Native;
using System.Security;
namespace GostCryptography.Gost_R3410
{
/// <summary>
/// Реализация алгоритма ГОСТ Р 34.10-2012/256 на основе эфимерного ключа
/// </summary>
public sealed class Gost_R3410_2012_256_EphemeralAsymmetricAlgorithm : Gost_R3410_EphemeralAsymmetricAlgorithm<Gost_R3410_2012_256_KeyExchangeParams, Gost_R3410_2012_256_KeyExchangeAlgorithm>
{
/// <summary>
/// Размер ключа ГОСТ Р 34.10-2012/256
/// </summary>
public const int DefaultKeySizeValue = 512;
/// <summary>
/// Наименование алгоритма цифровой подписи ГОСТ Р 34.10-2012 для ключей длины 256 бит
/// </summary>
public const string SignatureAlgorithmValue = "urn:ietf:params:xml:ns:cpxmlsec:algorithms:gostr34102012-gostr34112012-256";
/// <summary>
/// Наименование алгоритма обмена ключами ГОСТ Р 34.10-2012 для ключей длины 256 бит
/// </summary>
public const string KeyExchangeAlgorithmValue = "urn:ietf:params:xml:ns:cpxmlsec:algorithms:transport-gost2012-256";
/// <inheritdoc />
[SecuritySafeCritical]
public Gost_R3410_2012_256_EphemeralAsymmetricAlgorithm() : this(GostCryptoConfig.ProviderType_2012_512)
{
}
/// <inheritdoc />
[SecuritySafeCritical]
public Gost_R3410_2012_256_EphemeralAsymmetricAlgorithm(ProviderType providerType) : base(providerType, DefaultKeySizeValue)
{
}
/// <inheritdoc />
[SecuritySafeCritical]
public Gost_R3410_2012_256_EphemeralAsymmetricAlgorithm(Gost_R3410_2012_256_KeyExchangeParams keyParameters) : this(GostCryptoConfig.ProviderType_2012_512, keyParameters)
{
}
/// <inheritdoc />
[SecuritySafeCritical]
public Gost_R3410_2012_256_EphemeralAsymmetricAlgorithm(ProviderType providerType, Gost_R3410_2012_256_KeyExchangeParams keyParameters) : base(providerType, keyParameters, DefaultKeySizeValue)
{
}
/// <inheritdoc />
public override string AlgorithmName => SignatureAlgorithmValue;
/// <inheritdoc />
public override string SignatureAlgorithm => SignatureAlgorithmValue;
/// <inheritdoc />
public override string KeyExchangeAlgorithm => KeyExchangeAlgorithmValue;
/// <inheritdoc />
protected override int ExchangeAlgId => Constants.CALG_DH_GR3410_12_256_EPHEM;
/// <inheritdoc />
protected override int SignatureAlgId => Constants.CALG_GR3410_2012_256;
/// <inheritdoc />
protected override Gost_R3410_2012_256_KeyExchangeParams CreateKeyExchangeParams()
{
return new Gost_R3410_2012_256_KeyExchangeParams();
}
/// <inheritdoc />
[SecuritySafeCritical]
protected override Gost_R3410_2012_256_KeyExchangeAlgorithm CreateKeyExchangeAlgorithm(ProviderType providerType, SafeProvHandleImpl provHandle, SafeKeyHandleImpl keyHandle, Gost_R3410_2012_256_KeyExchangeParams keyExchangeParameters)
{
return new Gost_R3410_2012_256_KeyExchangeAlgorithm(providerType, provHandle, keyHandle, keyExchangeParameters, KeySizeValue, SignatureAlgId);
}
/// <inheritdoc />
[SecuritySafeCritical]
public override GostHashAlgorithm CreateHashAlgorithm()
{
return new Gost_R3411_2012_256_HashAlgorithm(ProviderType, this.GetSafeHandle<SafeProvHandleImpl>());
}
/// <inheritdoc />
public override GostKeyExchangeFormatter CreateKeyExchangeFormatter()
{
return new Gost_R3410_2012_256_KeyExchangeFormatter(this);
}
/// <inheritdoc />
public override GostKeyExchangeDeformatter CreateKeyExchangeDeformatter()
{
return new Gost_R3410_2012_256_KeyExchangeDeformatter(this);
}
/// <inheritdoc />
protected override Gost_R3410_KeyExchangeXmlSerializer<Gost_R3410_2012_256_KeyExchangeParams> CreateKeyExchangeXmlSerializer()
{
return new Gost_R3410_2012_256_KeyExchangeXmlSerializer();
}
}
}

View File

@ -0,0 +1,18 @@
using GostCryptography.Asn1.Gost.Gost_R3410_2012_256;
using GostCryptography.Base;
using GostCryptography.Native;
using System.Security;
namespace GostCryptography.Gost_R3410
{
/// <inheritdoc />
public sealed class Gost_R3410_2012_256_KeyExchangeAlgorithm : Gost_R3410_KeyExchangeAlgorithm
{
/// <inheritdoc />
[SecurityCritical]
public Gost_R3410_2012_256_KeyExchangeAlgorithm(ProviderType providerType, SafeProvHandleImpl provHandle, SafeKeyHandleImpl keyHandle, Gost_R3410_2012_256_KeyExchangeParams keyExchangeParameters, int keySize, int signatureAlgId)
: base(providerType, provHandle, keyHandle, keyExchangeParameters, keySize, signatureAlgId)
{
}
}
}

View File

@ -0,0 +1,24 @@
using GostCryptography.Asn1.Gost.Gost_R3410_2012_256;
using System.Security.Cryptography;
namespace GostCryptography.Gost_R3410
{
/// <summary>
/// Реализация дешифрования общего секретного ключа по ГОСТ Р 34.10-2012/256
/// </summary>
public sealed class Gost_R3410_2012_256_KeyExchangeDeformatter : Gost_R3410_KeyExchangeDeformatter<
Gost_R3410_2012_256_KeyExchange,
Gost_R3410_2012_256_KeyExchangeParams,
Gost_R3410_2012_256_KeyExchangeAlgorithm>
{
/// <inheritdoc />
public Gost_R3410_2012_256_KeyExchangeDeformatter()
{
}
/// <inheritdoc />
public Gost_R3410_2012_256_KeyExchangeDeformatter(AsymmetricAlgorithm privateKey) : base(privateKey)
{
}
}
}

View File

@ -0,0 +1,31 @@
using GostCryptography.Asn1.Gost.Gost_R3410_2012_256;
using GostCryptography.Base;
using System.Security.Cryptography;
namespace GostCryptography.Gost_R3410
{
/// <summary>
/// Реализация шифрования общего секретного ключа по ГОСТ Р 34.10-2012/256
/// </summary>
public sealed class Gost_R3410_2012_256_KeyExchangeFormatter : Gost_R3410_KeyExchangeFormatter<
Gost_R3410_2012_256_KeyExchange,
Gost_R3410_2012_256_KeyExchangeParams,
Gost_R3410_2012_256_KeyExchangeAlgorithm>
{
/// <inheritdoc />
public Gost_R3410_2012_256_KeyExchangeFormatter()
{
}
/// <inheritdoc />
public Gost_R3410_2012_256_KeyExchangeFormatter(AsymmetricAlgorithm publicKey) : base(publicKey)
{
}
/// <inheritdoc />
protected override Gost_R3410_EphemeralAsymmetricAlgorithm<Gost_R3410_2012_256_KeyExchangeParams, Gost_R3410_2012_256_KeyExchangeAlgorithm> CreateEphemeralAlgorithm(ProviderType providerType, Gost_R3410_2012_256_KeyExchangeParams keyExchangeParameters)
{
return new Gost_R3410_2012_256_EphemeralAsymmetricAlgorithm(providerType, keyExchangeParameters);
}
}
}

View File

@ -0,0 +1,20 @@
using GostCryptography.Asn1.Gost.Gost_R3410_2012_256;
namespace GostCryptography.Gost_R3410
{
/// <summary>
/// XML-сериализатора параметров ключа цифровой подписи ГОСТ Р 34.10-2012/256
/// </summary>
public sealed class Gost_R3410_2012_256_KeyExchangeXmlSerializer : Gost_R3410_KeyExchangeXmlSerializer<Gost_R3410_2012_256_KeyExchangeParams>
{
/// <summary>
/// Имя тега с информацией о параметрах ключа ГОСТ Р 34.10-2012/256
/// </summary>
public const string KeyValueTag = "Gost_R3410_2012_256_KeyValue";
/// <inheritdoc />
public Gost_R3410_2012_256_KeyExchangeXmlSerializer() : base(KeyValueTag)
{
}
}
}

View File

@ -0,0 +1,20 @@
using GostCryptography.Base;
using GostCryptography.Gost_R3411;
namespace GostCryptography.Gost_R3410
{
/// <summary>
/// Информация о свойствах цифровой подписи ГОСТ Р 34.10-2012/256
/// </summary>
public sealed class Gost_R3410_2012_256_SignatureDescription : GostSignatureDescription
{
/// <inheritdoc />
public Gost_R3410_2012_256_SignatureDescription()
{
KeyAlgorithm = typeof(Gost_R3410_2012_256_AsymmetricAlgorithm).AssemblyQualifiedName;
DigestAlgorithm = typeof(Gost_R3411_2012_256_HashAlgorithm).AssemblyQualifiedName;
FormatterAlgorithm = typeof(GostSignatureFormatter).AssemblyQualifiedName;
DeformatterAlgorithm = typeof(GostSignatureDeformatter).AssemblyQualifiedName;
}
}
}

View File

@ -0,0 +1,122 @@
using GostCryptography.Asn1.Gost.Gost_R3410_2012_512;
using GostCryptography.Base;
using GostCryptography.Config;
using GostCryptography.Gost_R3411;
using GostCryptography.Native;
using GostCryptography.Properties;
using System.Security;
using System.Security.Cryptography;
namespace GostCryptography.Gost_R3410
{
/// <summary>
/// Реализация алгоритма ГОСТ Р 34.10-2012/512
/// </summary>
public sealed class Gost_R3410_2012_512_AsymmetricAlgorithm : Gost_R3410_AsymmetricAlgorithm<Gost_R3410_2012_512_KeyExchangeParams, Gost_R3410_2012_512_KeyExchangeAlgorithm>
{
/// <summary>
/// Размер ключа ГОСТ Р 34.10-2012/512
/// </summary>
public const int DefaultKeySizeValue = 1024;
/// <summary>
/// Наименование алгоритма цифровой подписи ГОСТ Р 34.10-2012/512
/// </summary>
public const string SignatureAlgorithmValue = "urn:ietf:params:xml:ns:cpxmlsec:algorithms:gostr34102012-gostr34112012-512";
/// <summary>
/// Наименование алгоритма обмена ключами ГОСТ Р 34.10-2012/512
/// </summary>
public const string KeyExchangeAlgorithmValue = "urn:ietf:params:xml:ns:cpxmlsec:algorithms:transport-gost2012-512";
/// <summary>
/// Известные наименования алгоритма цифровой подписи ГОСТ Р 34.10-2012/512
/// </summary>
public static readonly string[] KnownSignatureAlgorithmNames = { SignatureAlgorithmValue };
/// <inheritdoc />
[SecuritySafeCritical]
public Gost_R3410_2012_512_AsymmetricAlgorithm() : this(GostCryptoConfig.ProviderType_2012_1024)
{
}
/// <inheritdoc />
[SecuritySafeCritical]
public Gost_R3410_2012_512_AsymmetricAlgorithm(ProviderType providerType) : base(providerType, DefaultKeySizeValue)
{
}
/// <inheritdoc />
[SecuritySafeCritical]
public Gost_R3410_2012_512_AsymmetricAlgorithm(CspParameters providerParameters) : base(providerParameters, DefaultKeySizeValue)
{
}
/// <inheritdoc />
public override string AlgorithmName => SignatureAlgorithmValue;
/// <inheritdoc />
public override string SignatureAlgorithm => SignatureAlgorithmValue;
/// <inheritdoc />
public override string KeyExchangeAlgorithm => KeyExchangeAlgorithmValue;
/// <inheritdoc />
protected override int ExchangeAlgId => Constants.CALG_DH_GR3410_2012_512_SF;
/// <inheritdoc />
protected override int SignatureAlgId => Constants.CALG_GR3410_2012_512;
/// <inheritdoc />
protected override Gost_R3410_2012_512_KeyExchangeParams CreateKeyExchangeParams()
{
return new Gost_R3410_2012_512_KeyExchangeParams();
}
/// <inheritdoc />
[SecuritySafeCritical]
protected override Gost_R3410_2012_512_KeyExchangeAlgorithm CreateKeyExchangeAlgorithm(ProviderType providerType, SafeProvHandleImpl provHandle, SafeKeyHandleImpl keyHandle, Gost_R3410_2012_512_KeyExchangeParams keyExchangeParameters)
{
return new Gost_R3410_2012_512_KeyExchangeAlgorithm(providerType, provHandle, keyHandle, keyExchangeParameters, KeySizeValue, SignatureAlgId);
}
/// <inheritdoc />
[SecuritySafeCritical]
public override GostHashAlgorithm CreateHashAlgorithm()
{
return new Gost_R3411_2012_512_HashAlgorithm(ProviderType, this.GetSafeHandle<SafeProvHandleImpl>());
}
/// <inheritdoc />
protected override void ValidateHashParameter(byte[] hash)
{
if (hash == null)
{
throw ExceptionUtility.ArgumentNull(nameof(hash));
}
if (hash.Length != Gost_R3411_2012_512_HashAlgorithm.DefaultHashSizeValue / 8)
{
throw ExceptionUtility.ArgumentOutOfRange(nameof(hash), Resources.InvalidHashSize, Gost_R3411_2012_512_HashAlgorithm.DefaultHashSizeValue / 8);
}
}
/// <inheritdoc />
public override GostKeyExchangeFormatter CreateKeyExchangeFormatter()
{
return new Gost_R3410_2012_512_KeyExchangeFormatter(this);
}
/// <inheritdoc />
public override GostKeyExchangeDeformatter CreateKeyExchangeDeformatter()
{
return new Gost_R3410_2012_512_KeyExchangeDeformatter(this);
}
/// <inheritdoc />
protected override Gost_R3410_KeyExchangeXmlSerializer<Gost_R3410_2012_512_KeyExchangeParams> CreateKeyExchangeXmlSerializer()
{
return new Gost_R3410_2012_512_KeyExchangeXmlSerializer();
}
}
}

View File

@ -0,0 +1,107 @@
using GostCryptography.Asn1.Gost.Gost_R3410_2012_512;
using GostCryptography.Base;
using GostCryptography.Config;
using GostCryptography.Gost_R3411;
using GostCryptography.Native;
using System.Security;
namespace GostCryptography.Gost_R3410
{
/// <summary>
/// Реализация алгоритма ГОСТ Р 34.10-2012/512 на основе эфимерного ключа
/// </summary>
public sealed class Gost_R3410_2012_512_EphemeralAsymmetricAlgorithm : Gost_R3410_EphemeralAsymmetricAlgorithm<Gost_R3410_2012_512_KeyExchangeParams, Gost_R3410_2012_512_KeyExchangeAlgorithm>
{
/// <summary>
/// Размер ключа ГОСТ Р 34.10-2012/512
/// </summary>
public const int DefaultKeySizeValue = 1024;
/// <summary>
/// Наименование алгоритма цифровой подписи ГОСТ Р 34.10-2012 для ключей длины 512 бит
/// </summary>
public const string SignatureAlgorithmValue = "urn:ietf:params:xml:ns:cpxmlsec:algorithms:gostr34102012-gostr34112012-512";
/// <summary>
/// Наименование алгоритма обмена ключами ГОСТ Р 34.10-2012 для ключей длины 512 бит
/// </summary>
public const string KeyExchangeAlgorithmValue = "urn:ietf:params:xml:ns:cpxmlsec:algorithms:transport-gost2012-512";
/// <inheritdoc />
[SecuritySafeCritical]
public Gost_R3410_2012_512_EphemeralAsymmetricAlgorithm() : this(GostCryptoConfig.ProviderType_2012_1024)
{
}
/// <inheritdoc />
[SecuritySafeCritical]
public Gost_R3410_2012_512_EphemeralAsymmetricAlgorithm(ProviderType providerType) : base(providerType, DefaultKeySizeValue)
{
}
/// <inheritdoc />
[SecuritySafeCritical]
public Gost_R3410_2012_512_EphemeralAsymmetricAlgorithm(Gost_R3410_2012_512_KeyExchangeParams keyParameters) : this(GostCryptoConfig.ProviderType_2012_1024, keyParameters)
{
}
/// <inheritdoc />
[SecuritySafeCritical]
public Gost_R3410_2012_512_EphemeralAsymmetricAlgorithm(ProviderType providerType, Gost_R3410_2012_512_KeyExchangeParams keyParameters) : base(providerType, keyParameters, DefaultKeySizeValue)
{
}
/// <inheritdoc />
public override string AlgorithmName => SignatureAlgorithmValue;
/// <inheritdoc />
public override string SignatureAlgorithm => SignatureAlgorithmValue;
/// <inheritdoc />
public override string KeyExchangeAlgorithm => KeyExchangeAlgorithmValue;
/// <inheritdoc />
protected override int ExchangeAlgId => Constants.CALG_DH_GR3410_12_512_EPHEM;
/// <inheritdoc />
protected override int SignatureAlgId => Constants.CALG_GR3410_2012_512;
/// <inheritdoc />
protected override Gost_R3410_2012_512_KeyExchangeParams CreateKeyExchangeParams()
{
return new Gost_R3410_2012_512_KeyExchangeParams();
}
/// <inheritdoc />
[SecuritySafeCritical]
protected override Gost_R3410_2012_512_KeyExchangeAlgorithm CreateKeyExchangeAlgorithm(ProviderType providerType, SafeProvHandleImpl provHandle, SafeKeyHandleImpl keyHandle, Gost_R3410_2012_512_KeyExchangeParams keyExchangeParameters)
{
return new Gost_R3410_2012_512_KeyExchangeAlgorithm(providerType, provHandle, keyHandle, keyExchangeParameters, KeySizeValue, SignatureAlgId);
}
/// <inheritdoc />
[SecuritySafeCritical]
public override GostHashAlgorithm CreateHashAlgorithm()
{
return new Gost_R3411_2012_512_HashAlgorithm(ProviderType, this.GetSafeHandle<SafeProvHandleImpl>());
}
/// <inheritdoc />
public override GostKeyExchangeFormatter CreateKeyExchangeFormatter()
{
return new Gost_R3410_2012_512_KeyExchangeFormatter(this);
}
/// <inheritdoc />
public override GostKeyExchangeDeformatter CreateKeyExchangeDeformatter()
{
return new Gost_R3410_2012_512_KeyExchangeDeformatter(this);
}
/// <inheritdoc />
protected override Gost_R3410_KeyExchangeXmlSerializer<Gost_R3410_2012_512_KeyExchangeParams> CreateKeyExchangeXmlSerializer()
{
return new Gost_R3410_2012_512_KeyExchangeXmlSerializer();
}
}
}

View File

@ -0,0 +1,18 @@
using GostCryptography.Asn1.Gost.Gost_R3410_2012_512;
using GostCryptography.Base;
using GostCryptography.Native;
using System.Security;
namespace GostCryptography.Gost_R3410
{
/// <inheritdoc />
public sealed class Gost_R3410_2012_512_KeyExchangeAlgorithm : Gost_R3410_KeyExchangeAlgorithm
{
/// <inheritdoc />
[SecurityCritical]
public Gost_R3410_2012_512_KeyExchangeAlgorithm(ProviderType providerType, SafeProvHandleImpl provHandle, SafeKeyHandleImpl keyHandle, Gost_R3410_2012_512_KeyExchangeParams keyExchangeParameters, int keySize, int signatureAlgId)
: base(providerType, provHandle, keyHandle, keyExchangeParameters, keySize, signatureAlgId)
{
}
}
}

View File

@ -0,0 +1,24 @@
using GostCryptography.Asn1.Gost.Gost_R3410_2012_512;
using System.Security.Cryptography;
namespace GostCryptography.Gost_R3410
{
/// <summary>
/// Реализация дешифрования общего секретного ключа по ГОСТ Р 34.10-2012/512
/// </summary>
public sealed class Gost_R3410_2012_512_KeyExchangeDeformatter : Gost_R3410_KeyExchangeDeformatter<
Gost_R3410_2012_512_KeyExchange,
Gost_R3410_2012_512_KeyExchangeParams,
Gost_R3410_2012_512_KeyExchangeAlgorithm>
{
/// <inheritdoc />
public Gost_R3410_2012_512_KeyExchangeDeformatter()
{
}
/// <inheritdoc />
public Gost_R3410_2012_512_KeyExchangeDeformatter(AsymmetricAlgorithm privateKey) : base(privateKey)
{
}
}
}

View File

@ -0,0 +1,31 @@
using GostCryptography.Asn1.Gost.Gost_R3410_2012_512;
using GostCryptography.Base;
using System.Security.Cryptography;
namespace GostCryptography.Gost_R3410
{
/// <summary>
/// Реализация шифрования общего секретного ключа по ГОСТ Р 34.10-2012/512
/// </summary>
public sealed class Gost_R3410_2012_512_KeyExchangeFormatter : Gost_R3410_KeyExchangeFormatter<
Gost_R3410_2012_512_KeyExchange,
Gost_R3410_2012_512_KeyExchangeParams,
Gost_R3410_2012_512_KeyExchangeAlgorithm>
{
/// <inheritdoc />
public Gost_R3410_2012_512_KeyExchangeFormatter()
{
}
/// <inheritdoc />
public Gost_R3410_2012_512_KeyExchangeFormatter(AsymmetricAlgorithm publicKey) : base(publicKey)
{
}
/// <inheritdoc />
protected override Gost_R3410_EphemeralAsymmetricAlgorithm<Gost_R3410_2012_512_KeyExchangeParams, Gost_R3410_2012_512_KeyExchangeAlgorithm> CreateEphemeralAlgorithm(ProviderType providerType, Gost_R3410_2012_512_KeyExchangeParams keyExchangeParameters)
{
return new Gost_R3410_2012_512_EphemeralAsymmetricAlgorithm(providerType, keyExchangeParameters);
}
}
}

View File

@ -0,0 +1,20 @@
using GostCryptography.Asn1.Gost.Gost_R3410_2012_512;
namespace GostCryptography.Gost_R3410
{
/// <summary>
/// XML-сериализатора параметров ключа цифровой подписи ГОСТ Р 34.10-2012/512
/// </summary>
public sealed class Gost_R3410_2012_512_KeyExchangeXmlSerializer : Gost_R3410_KeyExchangeXmlSerializer<Gost_R3410_2012_512_KeyExchangeParams>
{
/// <summary>
/// Имя тега с информацией о параметрах ключа ГОСТ Р 34.10-2012/512
/// </summary>
public const string KeyValueTag = "Gost_R3410_2012_512_KeyValue";
/// <inheritdoc />
public Gost_R3410_2012_512_KeyExchangeXmlSerializer() : base(KeyValueTag)
{
}
}
}

View File

@ -0,0 +1,20 @@
using GostCryptography.Base;
using GostCryptography.Gost_R3411;
namespace GostCryptography.Gost_R3410
{
/// <summary>
/// Информация о свойствах цифровой подписи ГОСТ Р 34.10-2012/512
/// </summary>
public sealed class Gost_R3410_2012_512_SignatureDescription : GostSignatureDescription
{
/// <inheritdoc />
public Gost_R3410_2012_512_SignatureDescription()
{
KeyAlgorithm = typeof(Gost_R3410_2012_512_AsymmetricAlgorithm).AssemblyQualifiedName;
DigestAlgorithm = typeof(Gost_R3411_2012_512_HashAlgorithm).AssemblyQualifiedName;
FormatterAlgorithm = typeof(GostSignatureFormatter).AssemblyQualifiedName;
DeformatterAlgorithm = typeof(GostSignatureDeformatter).AssemblyQualifiedName;
}
}
}

View File

@ -0,0 +1,636 @@
using GostCryptography.Asn1.Gost.Gost_R3410;
using GostCryptography.Base;
using GostCryptography.Native;
using GostCryptography.Properties;
using GostCryptography.Reflection;
using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Security;
using System.Security.Cryptography;
using System.Security.Permissions;
namespace GostCryptography.Gost_R3410
{
/// <inheritdoc cref="Gost_R3410_AsymmetricAlgorithmBase{TKeyParams,TKeyAlgorithm}" />
public abstract class Gost_R3410_AsymmetricAlgorithm<TKeyParams, TKeyAlgorithm> : Gost_R3410_AsymmetricAlgorithmBase<TKeyParams, TKeyAlgorithm>, ICspAsymmetricAlgorithm, ISafeHandleProvider<SafeProvHandleImpl>, ISafeHandleProvider<SafeKeyHandleImpl>
where TKeyParams : Gost_R3410_KeyExchangeParams
where TKeyAlgorithm : Gost_R3410_KeyExchangeAlgorithm
{
/// <inheritdoc />
[SecuritySafeCritical]
protected Gost_R3410_AsymmetricAlgorithm(ProviderType providerType, int keySize) : base(providerType, keySize)
{
_providerParameters = CreateDefaultProviderParameters();
InitKeyContainer(_providerParameters, out _isRandomKeyContainer);
}
/// <summary>
/// Конструктор
/// </summary>
/// <param name="providerParameters">Параметры криптографического провайдера</param>
/// <param name="keySize">Размер ключа в битах</param>
[SecuritySafeCritical]
protected Gost_R3410_AsymmetricAlgorithm(CspParameters providerParameters, int keySize) : base((ProviderType)providerParameters.ProviderType, keySize)
{
_providerParameters = CopyExistingProviderParameters(providerParameters);
InitKeyContainer(_providerParameters, out _isRandomKeyContainer);
}
private readonly CspParameters _providerParameters;
private readonly bool _isRandomKeyContainer;
private bool _isPersistentKey;
private bool _isPublicKeyOnly;
[SecurityCritical]
private SafeProvHandleImpl _providerHandle;
[SecurityCritical]
private volatile SafeKeyHandleImpl _keyHandle;
/// <inheritdoc />
SafeProvHandleImpl ISafeHandleProvider<SafeProvHandleImpl>.SafeHandle
{
[SecurityCritical]
get
{
GetKeyPair();
return _providerHandle;
}
}
/// <inheritdoc />
SafeKeyHandleImpl ISafeHandleProvider<SafeKeyHandleImpl>.SafeHandle
{
[SecurityCritical]
get
{
GetKeyPair();
return _keyHandle;
}
}
/// <inheritdoc />
public override int KeySize
{
[SecuritySafeCritical]
get
{
GetKeyPair();
return base.KeySize;
}
}
/// <summary>
/// Хранить ключ в криптографическом провайдере
/// </summary>
public bool IsPersistentKey
{
[SecuritySafeCritical]
get
{
if (_providerHandle == null)
{
lock (this)
{
if (_providerHandle == null)
{
_providerHandle = CreateProviderHandle(_providerParameters, _isRandomKeyContainer);
}
}
}
return _isPersistentKey;
}
[SecuritySafeCritical]
set
{
var currentValue = IsPersistentKey;
if (currentValue != value)
{
var keyContainerPermission = new KeyContainerPermission(KeyContainerPermissionFlags.NoFlags);
var containerAccessEntry = new KeyContainerPermissionAccessEntry(_providerParameters, value ? KeyContainerPermissionFlags.Create : KeyContainerPermissionFlags.Delete);
keyContainerPermission.AccessEntries.Add(containerAccessEntry);
keyContainerPermission.Demand();
_isPersistentKey = value;
_providerHandle.DeleteOnClose = !_isPersistentKey;
}
}
}
/// <summary>
/// Имеется доступ только к открытому ключу
/// </summary>
public bool IsPublicKeyOnly
{
[SecuritySafeCritical]
get
{
GetKeyPair();
return _isPublicKeyOnly;
}
}
/// <inheritdoc />
public CspKeyContainerInfo CspKeyContainerInfo
{
[SecuritySafeCritical]
get
{
GetKeyPair();
return CspKeyContainerInfoHelper.CreateCspKeyContainerInfo(_providerParameters, _isRandomKeyContainer);
}
}
/// <inheritdoc />
[SecuritySafeCritical]
public byte[] ExportCspBlob(bool includePrivateParameters)
{
GetKeyPair();
if (includePrivateParameters)
{
throw ExceptionUtility.CryptographicException(Resources.UserExportBulkBlob);
}
return CryptoApiHelper.ExportCspBlob(_keyHandle, SafeKeyHandleImpl.InvalidHandle, Constants.PUBLICKEYBLOB);
}
/// <inheritdoc />
[SecuritySafeCritical]
public void ImportCspBlob(byte[] importedKeyBytes)
{
if (importedKeyBytes == null)
{
throw ExceptionUtility.ArgumentNull(nameof(importedKeyBytes));
}
if (!IsPublicKeyBlob(importedKeyBytes))
{
throw ExceptionUtility.Argument(nameof(importedKeyBytes), Resources.UserImportBulkBlob);
}
var hProv = CryptoApiHelper.GetProviderHandle(ProviderType);
_providerParameters.KeyNumber = CryptoApiHelper.ImportCspBlob(importedKeyBytes, hProv, SafeKeyHandleImpl.InvalidHandle, out var hKey);
_providerHandle = hProv;
_keyHandle = hKey;
_isPublicKeyOnly = true;
}
[SecuritySafeCritical]
public void ImportCspBlob(byte[] encodedParameters, byte[] encodedKeyValue)
{
var keyParams = CreateKeyExchangeParams();
keyParams.DecodeParameters(encodedParameters);
keyParams.DecodePublicKey(encodedKeyValue);
var keyBytes = CryptoApiHelper.EncodePublicBlob(keyParams, KeySizeValue, SignatureAlgId);
ImportCspBlob(keyBytes);
}
private static bool IsPublicKeyBlob(byte[] importedKeyBytes)
{
if ((importedKeyBytes[0] != Constants.PUBLICKEYBLOB) || (importedKeyBytes.Length < 12))
{
return false;
}
var gostKeyMask = BitConverter.GetBytes(Constants.GR3410_1_MAGIC);
return (importedKeyBytes[8] == gostKeyMask[0])
&& (importedKeyBytes[9] == gostKeyMask[1])
&& (importedKeyBytes[10] == gostKeyMask[2])
&& (importedKeyBytes[11] == gostKeyMask[3]);
}
/// <inheritdoc />
public override byte[] CreateSignature(byte[] hash)
{
return SignHash(hash);
}
/// <summary>
/// Вычисляет цифровую подпись
/// </summary>
[SecuritySafeCritical]
public byte[] CreateSignature(byte[] data, object hashAlgorithm)
{
var hash = CryptographyUtils.ObjToHashAlgorithm(hashAlgorithm).ComputeHash(data);
return SignHash(hash);
}
/// <summary>
/// Вычисляет цифровую подпись
/// </summary>
[SecuritySafeCritical]
public byte[] CreateSignature(Stream data, object hashAlgorithm)
{
var hash = CryptographyUtils.ObjToHashAlgorithm(hashAlgorithm).ComputeHash(data);
return SignHash(hash);
}
/// <summary>
/// Вычисляет цифровую подпись
/// </summary>
[SecuritySafeCritical]
public byte[] CreateSignature(byte[] data, int dataOffset, int dataLength, object hashAlgorithm)
{
var hash = CryptographyUtils.ObjToHashAlgorithm(hashAlgorithm).ComputeHash(data, dataOffset, dataLength);
return SignHash(hash);
}
[SecuritySafeCritical]
private byte[] SignHash(byte[] hash)
{
ValidateHashParameter(hash);
if (IsPublicKeyOnly)
{
throw ExceptionUtility.CryptographicException(Resources.NoPrivateKey);
}
GetKeyPair();
if (!CspKeyContainerInfo.RandomlyGenerated)
{
var keyContainerPermission = new KeyContainerPermission(KeyContainerPermissionFlags.NoFlags);
var keyContainerAccessEntry = new KeyContainerPermissionAccessEntry(_providerParameters, KeyContainerPermissionFlags.Sign);
keyContainerPermission.AccessEntries.Add(keyContainerAccessEntry);
keyContainerPermission.Demand();
}
using (var hashAlgorithm = CreateHashAlgorithm())
{
var hashHandleProvider = (ISafeHandleProvider<SafeHashHandleImpl>)hashAlgorithm;
return CryptoApiHelper.SignValue(_providerHandle, hashHandleProvider.SafeHandle, _providerParameters.KeyNumber, hash);
}
}
/// <inheritdoc />
public override bool VerifySignature(byte[] hash, byte[] signature)
{
return VerifyHash(hash, signature);
}
/// <summary>
/// Проверяет цифровую подпись
/// </summary>
[SecuritySafeCritical]
public bool VerifySignature(byte[] buffer, object hashAlgorithm, byte[] signature)
{
var hash = CryptographyUtils.ObjToHashAlgorithm(hashAlgorithm).ComputeHash(buffer);
return VerifyHash(hash, signature);
}
/// <summary>
/// Проверяет цифровую подпись
/// </summary>
[SecuritySafeCritical]
public bool VerifySignature(Stream inputStream, object hashAlgorithm, byte[] signature)
{
var hash = CryptographyUtils.ObjToHashAlgorithm(hashAlgorithm).ComputeHash(inputStream);
return VerifyHash(hash, signature);
}
/// <summary>
/// Проверяет цифровую подпись
/// </summary>
public bool VerifySignature(byte[] data, int dataOffset, int dataLength, object hashAlgorithm, byte[] signature)
{
var hash = CryptographyUtils.ObjToHashAlgorithm(hashAlgorithm).ComputeHash(data, dataOffset, dataLength);
return VerifyHash(hash, signature);
}
[SecuritySafeCritical]
private bool VerifyHash(byte[] hash, byte[] signature)
{
ValidateHashParameter(hash);
if (signature == null)
{
throw ExceptionUtility.ArgumentNull(nameof(signature));
}
GetKeyPair();
using (var hashAlgorithm = CreateHashAlgorithm())
{
var hashHandleProvider = (ISafeHandleProvider<SafeHashHandleImpl>)hashAlgorithm;
return CryptoApiHelper.VerifySign(_providerHandle, hashHandleProvider.SafeHandle, _keyHandle, hash, signature);
}
}
/// <summary>
/// Проверяет корректность хэша
/// </summary>
protected abstract void ValidateHashParameter(byte[] hash);
/// <inheritdoc />
[SecuritySafeCritical]
public override TKeyAlgorithm CreateKeyExchange(TKeyParams keyParameters)
{
GetKeyPair();
return CreateKeyExchangeAlgorithm(ProviderType, _providerHandle, _keyHandle, (TKeyParams)keyParameters.Clone());
}
/// <inheritdoc />
[SecuritySafeCritical]
public override TKeyParams ExportParameters(bool includePrivateKey)
{
if (includePrivateKey)
{
throw ExceptionUtility.NotSupported(Resources.UserExportBulkKeyNotSupported);
}
GetKeyPair();
return CryptoApiHelper.ExportPublicKey(_keyHandle, CreateKeyExchangeParams(), KeySizeValue);
}
/// <inheritdoc />
[SecuritySafeCritical]
public override void ImportParameters(TKeyParams keyParameters)
{
if (keyParameters.PrivateKey != null)
{
throw ExceptionUtility.NotSupported(Resources.UserImportBulkKeyNotSupported);
}
_keyHandle.TryDispose();
var hProv = CryptoApiHelper.GetProviderHandle(ProviderType);
var importedKeyBytes = CryptoApiHelper.EncodePublicBlob(keyParameters.Clone(), KeySizeValue, SignatureAlgId);
_providerParameters.KeyNumber = CryptoApiHelper.ImportCspBlob(importedKeyBytes, hProv, SafeKeyHandleImpl.InvalidHandle, out var keyHandle);
_providerHandle = hProv;
_keyHandle = keyHandle;
_isPublicKeyOnly = true;
}
/// <summary>
/// Установка пароля доступа к контейнеру
/// </summary>
[SecuritySafeCritical]
[SecurityPermission(SecurityAction.Assert, UnmanagedCode = true)]
public void SetContainerPassword(SecureString password)
{
if (IsPublicKeyOnly)
{
throw ExceptionUtility.CryptographicException(Resources.NoPrivateKey);
}
GetKeyPair();
SetSignatureKeyPassword(_providerHandle, password, _providerParameters.KeyNumber);
}
/// <inheritdoc />
[SecuritySafeCritical]
protected override void Dispose(bool disposing)
{
_keyHandle.TryDispose();
if (!_isPublicKeyOnly)
{
_providerHandle.TryDispose();
}
base.Dispose(disposing);
}
[SecurityCritical]
private void GetKeyPair()
{
if (_keyHandle == null)
{
lock (this)
{
if (_keyHandle == null)
{
GetKeyPairValue(_providerParameters, _isRandomKeyContainer, out var providerHandle, out var keyHandle);
_providerHandle = providerHandle;
_keyHandle = keyHandle;
_isPersistentKey = true;
}
}
}
}
[SecurityCritical]
private void GetKeyPairValue(CspParameters providerParams, bool randomKeyContainer, out SafeProvHandleImpl providerHandle, out SafeKeyHandleImpl keyHandle)
{
SafeProvHandleImpl resultProviderHandle = null;
SafeKeyHandleImpl resultKeyHandle = null;
try
{
resultProviderHandle = CreateProviderHandle(providerParams, randomKeyContainer);
if (providerParams.ParentWindowHandle != IntPtr.Zero)
{
CryptoApiHelper.SetProviderParameter(resultProviderHandle, providerParams.KeyNumber, Constants.PP_CLIENT_HWND, providerParams.ParentWindowHandle);
}
else if (providerParams.KeyPassword != null)
{
SetSignatureKeyPassword(resultProviderHandle, providerParams.KeyPassword, providerParams.KeyNumber);
}
try
{
resultKeyHandle = CryptoApiHelper.GetUserKey(resultProviderHandle, providerParams.KeyNumber);
}
catch (Exception exception)
{
var errorCode = Marshal.GetHRForException(exception);
if (errorCode != 0)
{
if (((providerParams.Flags & CspProviderFlags.UseExistingKey) != CspProviderFlags.NoFlags) || (errorCode != Constants.NTE_NO_KEY))
{
throw;
}
resultKeyHandle = CryptoApiHelper.GenerateKey(resultProviderHandle, providerParams.KeyNumber, providerParams.Flags);
}
}
var keyAlgIdInverted = CryptoApiHelper.GetKeyParameter(resultKeyHandle, Constants.KP_ALGID);
var keyAlgId = keyAlgIdInverted[0] | (keyAlgIdInverted[1] << 8) | (keyAlgIdInverted[2] << 16) | (keyAlgIdInverted[3] << 24);
if ((keyAlgId != ExchangeAlgId) && (keyAlgId != SignatureAlgId))
{
throw ExceptionUtility.NotSupported(Resources.KeyAlgorithmNotSupported);
}
}
catch (Exception)
{
resultProviderHandle?.Close();
resultKeyHandle?.Close();
throw;
}
providerHandle = resultProviderHandle;
keyHandle = resultKeyHandle;
}
[SecurityCritical]
private static SafeProvHandleImpl CreateProviderHandle(CspParameters providerParams, bool randomKeyContainer)
{
SafeProvHandleImpl providerHandle = null;
var keyContainerPermission = new KeyContainerPermission(KeyContainerPermissionFlags.NoFlags);
try
{
providerHandle = CryptoApiHelper.OpenProvider(providerParams);
}
catch (Exception exception)
{
var errorCode = Marshal.GetHRForException(exception);
if (errorCode != 0)
{
if (((providerParams.Flags & CspProviderFlags.UseExistingKey) != CspProviderFlags.NoFlags)
|| ((errorCode != Constants.NTE_KEYSET_NOT_DEF)
&& (errorCode != Constants.NTE_BAD_KEYSET)
&& (errorCode != Constants.SCARD_W_CANCELLED_BY_USER)))
{
throw ExceptionUtility.CryptographicException(errorCode);
}
if (!randomKeyContainer)
{
var containerAccessEntry = new KeyContainerPermissionAccessEntry(providerParams, KeyContainerPermissionFlags.Create);
keyContainerPermission.AccessEntries.Add(containerAccessEntry);
keyContainerPermission.Demand();
}
providerHandle = CryptoApiHelper.CreateProvider(providerParams);
return providerHandle;
}
}
if (!randomKeyContainer)
{
var containerAccessEntry = new KeyContainerPermissionAccessEntry(providerParams, KeyContainerPermissionFlags.Open);
keyContainerPermission.AccessEntries.Add(containerAccessEntry);
keyContainerPermission.Demand();
}
return providerHandle;
}
[SecuritySafeCritical]
private static void SetSignatureKeyPassword(SafeProvHandleImpl hProv, SecureString keyPassword, int keyNumber)
{
if (keyPassword == null)
{
throw ExceptionUtility.ArgumentNull(nameof(keyPassword));
}
var keyPasswordData = Marshal.SecureStringToCoTaskMemAnsi(keyPassword);
try
{
CryptoApiHelper.SetProviderParameter(hProv, keyNumber, Constants.PP_SIGNATURE_PIN, keyPasswordData);
}
finally
{
if (keyPasswordData != IntPtr.Zero)
{
Marshal.ZeroFreeCoTaskMemAnsi(keyPasswordData);
}
}
}
private CspParameters CreateDefaultProviderParameters(CspProviderFlags defaultFlags = CspProviderFlags.UseMachineKeyStore)
{
return new CspParameters(ProviderType.ToInt())
{
Flags = defaultFlags
};
}
private CspParameters CopyExistingProviderParameters(CspParameters providerParameters)
{
ValidateProviderParameters(providerParameters.Flags);
return new CspParameters(providerParameters.ProviderType, providerParameters.ProviderName, providerParameters.KeyContainerName)
{
Flags = providerParameters.Flags,
KeyNumber = providerParameters.KeyNumber
};
}
private static void ValidateProviderParameters(CspProviderFlags flags)
{
// Если информацию о провайдере нужно взять из текущего ключа
if ((flags & CspProviderFlags.UseExistingKey) != CspProviderFlags.NoFlags)
{
const CspProviderFlags notExpectedFlags = CspProviderFlags.UseUserProtectedKey
| CspProviderFlags.UseArchivableKey
| CspProviderFlags.UseNonExportableKey;
if ((flags & notExpectedFlags) != CspProviderFlags.NoFlags)
{
throw ExceptionUtility.Argument(nameof(flags), Resources.InvalidCspProviderFlags);
}
}
// Если пользователь должен сам выбрать ключ (например, в диалоге)
if ((flags & CspProviderFlags.UseUserProtectedKey) != CspProviderFlags.NoFlags)
{
if (!Environment.UserInteractive)
{
throw ExceptionUtility.CryptographicException(Resources.UserInteractiveNotSupported);
}
new UIPermission(UIPermissionWindow.SafeTopLevelWindows).Demand();
}
}
[SecurityCritical]
private void InitKeyContainer(CspParameters providerParameters, out bool randomKeyContainer)
{
// Установка типа ключа
if (providerParameters.KeyNumber == -1)
{
providerParameters.KeyNumber = (int)KeyNumber.Exchange;
}
else if (providerParameters.KeyNumber == SignatureAlgId)
{
providerParameters.KeyNumber = (int)KeyNumber.Signature;
}
else if (providerParameters.KeyNumber == ExchangeAlgId)
{
providerParameters.KeyNumber = (int)KeyNumber.Exchange;
}
// Использовать автогенерированный контейнер
randomKeyContainer = ((providerParameters.KeyContainerName == null) && ((providerParameters.Flags & CspProviderFlags.UseDefaultKeyContainer) == CspProviderFlags.NoFlags));
if (randomKeyContainer)
{
providerParameters.KeyContainerName = Guid.NewGuid().ToString();
}
else
{
GetKeyPair();
}
}
}
}

View File

@ -0,0 +1,81 @@
using GostCryptography.Asn1.Gost.Gost_R3410;
using GostCryptography.Base;
using GostCryptography.Native;
using System.Security;
namespace GostCryptography.Gost_R3410
{
/// <summary>
/// Базовый класс для всех реализаций алгоритма ГОСТ Р 34.10
/// </summary>
/// <typeparam name="TKeyParams">Параметры ключа цифровой подписи ГОСТ Р 34.10</typeparam>
/// <typeparam name="TKeyAlgorithm">Алгоритм общего секретного ключа ГОСТ Р 34.10</typeparam>
public abstract class Gost_R3410_AsymmetricAlgorithmBase<TKeyParams, TKeyAlgorithm> : GostAsymmetricAlgorithm
where TKeyParams : Gost_R3410_KeyExchangeParams
where TKeyAlgorithm : Gost_R3410_KeyExchangeAlgorithm
{
/// <inheritdoc cref="GostAsymmetricAlgorithm(ProviderType,int)" />
protected Gost_R3410_AsymmetricAlgorithmBase(ProviderType providerType, int keySize) : base(providerType, keySize)
{
}
/// <summary>
/// Идентификатор алгоритма обмена ключей
/// </summary>
protected abstract int ExchangeAlgId { get; }
/// <summary>
/// Идентификатор алгоритма цифровой подписи
/// </summary>
protected abstract int SignatureAlgId { get; }
/// <summary>
/// Создает экземпляр <typeparamref name="TKeyParams"/>
/// </summary>
protected abstract TKeyParams CreateKeyExchangeParams();
/// <summary>
/// Создает экземпляр <typeparamref name="TKeyAlgorithm"/>
/// </summary>
[SecuritySafeCritical]
protected abstract TKeyAlgorithm CreateKeyExchangeAlgorithm(ProviderType providerType, SafeProvHandleImpl provHandle, SafeKeyHandleImpl keyHandle, TKeyParams keyExchangeParameters);
/// <summary>
/// Создает общий секретный ключ
/// </summary>
/// <param name="keyParameters">Параметры открытого ключа, используемого для создания общего секретного ключа</param>
public abstract TKeyAlgorithm CreateKeyExchange(TKeyParams keyParameters);
/// <summary>
/// Экспортирует (шифрует) параметры ключа, используемого для создания общего секретного ключа
/// </summary>
/// <param name="includePrivateKey">Включить секретный ключ</param>
public abstract TKeyParams ExportParameters(bool includePrivateKey);
/// <summary>
/// Импортирует (дешифрует) параметры ключа, используемого для создания общего секретного ключа
/// </summary>
/// <param name="keyParameters">Параметры ключа, используемого для создания общего секретного ключа</param>
public abstract void ImportParameters(TKeyParams keyParameters);
/// <summary>
/// Создает XML-сериализатор параметров ключа цифровой подписи
/// </summary>
protected abstract Gost_R3410_KeyExchangeXmlSerializer<TKeyParams> CreateKeyExchangeXmlSerializer();
/// <inheritdoc />
public override string ToXmlString(bool includePrivateKey)
{
var keyParameters = ExportParameters(includePrivateKey);
var xmlSerializer = CreateKeyExchangeXmlSerializer();
return xmlSerializer.Serialize(keyParameters);
}
/// <inheritdoc />
public override void FromXmlString(string keyParametersXml)
{
var xmlSerializer = CreateKeyExchangeXmlSerializer();
var keyParameters = xmlSerializer.Deserialize(keyParametersXml, CreateKeyExchangeParams());
ImportParameters(keyParameters);
}
}
}

View File

@ -0,0 +1,116 @@
using GostCryptography.Asn1.Gost.Gost_R3410;
using GostCryptography.Base;
using GostCryptography.Native;
using GostCryptography.Properties;
using System;
using System.Security;
using System.Security.Cryptography;
namespace GostCryptography.Gost_R3410
{
/// <summary>
/// Реализация алгоритма формирования общих ключей на основе алгоритма ГОСТ Р 34.10 и эфимерного ключа
/// </summary>
public abstract class Gost_R3410_EphemeralAsymmetricAlgorithm<TKeyParams, TKeyAlgorithm> : Gost_R3410_AsymmetricAlgorithmBase<TKeyParams, TKeyAlgorithm>, ISafeHandleProvider<SafeProvHandleImpl>, ISafeHandleProvider<SafeKeyHandleImpl>
where TKeyParams : Gost_R3410_KeyExchangeParams
where TKeyAlgorithm : Gost_R3410_KeyExchangeAlgorithm
{
/// <inheritdoc />
[SecuritySafeCritical]
protected Gost_R3410_EphemeralAsymmetricAlgorithm(ProviderType providerType, int keySize) : base(providerType, keySize)
{
_providerHandle = CryptoApiHelper.GetProviderHandle(ProviderType).DangerousAddRef();
_keyHandle = CryptoApiHelper.GenerateKey(_providerHandle, ExchangeAlgId, CspProviderFlags.NoFlags);
}
/// <summary>
/// Конструктор
/// </summary>
/// <param name="providerType">Тип криптографического провайдера</param>
/// <param name="keyParameters">Параметры ключа, используемого для создания общего секретного ключа</param>
/// <param name="keySize">Размер ключа в битах</param>
/// <exception cref="ArgumentNullException"></exception>
/// <remarks>
/// В параметре <paramref name="keyParameters"/> достаточно передать идентификатор OID параметров хэширования
/// <see cref="Gost_R3410_KeyExchangeParams.DigestParamSet"/> и идентификатор OID параметров открытого ключа
/// <see cref="Gost_R3410_KeyExchangeParams.PublicKeyParamSet"/>. Остальные параметры не используются.
/// </remarks>
[SecuritySafeCritical]
protected Gost_R3410_EphemeralAsymmetricAlgorithm(ProviderType providerType, TKeyParams keyParameters, int keySize) : base(providerType, keySize)
{
if (keyParameters == null)
{
throw ExceptionUtility.ArgumentNull(nameof(keyParameters));
}
_providerHandle = CryptoApiHelper.GetProviderHandle(ProviderType).DangerousAddRef();
_keyHandle = CryptoApiHelper.GenerateDhEphemeralKey(providerType, _providerHandle, ExchangeAlgId, keyParameters.DigestParamSet, keyParameters.PublicKeyParamSet);
}
[SecurityCritical]
private readonly SafeProvHandleImpl _providerHandle;
[SecurityCritical]
private readonly SafeKeyHandleImpl _keyHandle;
/// <inheritdoc />
SafeProvHandleImpl ISafeHandleProvider<SafeProvHandleImpl>.SafeHandle
{
[SecurityCritical]
get => _providerHandle;
}
/// <inheritdoc />
SafeKeyHandleImpl ISafeHandleProvider<SafeKeyHandleImpl>.SafeHandle
{
[SecurityCritical]
get => _keyHandle;
}
/// <inheritdoc />
public override byte[] CreateSignature(byte[] hash)
{
throw ExceptionUtility.NotSupported(Resources.EphemKeyOperationNotSupported);
}
/// <inheritdoc />
public override bool VerifySignature(byte[] hash, byte[] signature)
{
throw ExceptionUtility.NotSupported(Resources.EphemKeyOperationNotSupported);
}
/// <inheritdoc />
[SecuritySafeCritical]
public override TKeyAlgorithm CreateKeyExchange(TKeyParams keyParameters)
{
return CreateKeyExchangeAlgorithm(ProviderType, _providerHandle, _keyHandle, (TKeyParams)keyParameters.Clone());
}
/// <inheritdoc />
[SecuritySafeCritical]
public override TKeyParams ExportParameters(bool includePrivateKey)
{
if (includePrivateKey)
{
throw ExceptionUtility.NotSupported(Resources.EphemKeyOperationNotSupported);
}
return CryptoApiHelper.ExportPublicKey(_keyHandle, CreateKeyExchangeParams(), KeySizeValue);
}
/// <inheritdoc />
public override void ImportParameters(TKeyParams keyParameters)
{
throw ExceptionUtility.NotSupported(Resources.EphemKeyOperationNotSupported);
}
/// <inheritdoc />
[SecuritySafeCritical]
protected override void Dispose(bool disposing)
{
_keyHandle.TryDispose();
_providerHandle.TryDispose();
base.Dispose(disposing);
}
}
}

View File

@ -0,0 +1,163 @@
using GostCryptography.Asn1.Gost.Gost_28147_89;
using GostCryptography.Asn1.Gost.Gost_R3410;
using GostCryptography.Base;
using GostCryptography.Gost_28147_89;
using GostCryptography.Native;
using GostCryptography.Properties;
using System.Security;
using System.Security.Cryptography;
namespace GostCryptography.Gost_R3410
{
/// <summary>
/// Базовый класс всех реализаций общего секретного ключа ГОСТ Р 34.10
/// </summary>
public abstract class Gost_R3410_KeyExchangeAlgorithm : GostKeyExchangeAlgorithm
{
/// <inheritdoc />
[SecurityCritical]
protected Gost_R3410_KeyExchangeAlgorithm(ProviderType providerType, SafeProvHandleImpl provHandle, SafeKeyHandleImpl keyHandle, Gost_R3410_KeyExchangeParams keyExchangeParameters, int keySize, int signatureAlgId) : base(providerType)
{
if (provHandle == null)
{
throw ExceptionUtility.ArgumentNull(nameof(provHandle));
}
if (keyHandle == null)
{
throw ExceptionUtility.ArgumentNull(nameof(keyHandle));
}
if (keyExchangeParameters == null)
{
throw ExceptionUtility.ArgumentNull(nameof(keyExchangeParameters));
}
_provHandle = provHandle.DangerousAddRef();
_keyHandle = keyHandle.DangerousAddRef();
_keyExchangeParameters = keyExchangeParameters;
_keySize = keySize;
_signatureAlgId = signatureAlgId;
}
[SecurityCritical]
private readonly SafeProvHandleImpl _provHandle;
[SecurityCritical]
private readonly SafeKeyHandleImpl _keyHandle;
[SecurityCritical]
private readonly Gost_R3410_KeyExchangeParams _keyExchangeParameters;
private readonly int _keySize;
private readonly int _signatureAlgId;
/// <inheritdoc />
[SecuritySafeCritical]
public override byte[] EncodeKeyExchange(SymmetricAlgorithm keyExchangeAlgorithm, GostKeyExchangeExportMethod keyExchangeExportMethod)
{
if (keyExchangeAlgorithm is Gost_28147_89_SymmetricAlgorithm symAlg)
{
return EncodeKeyExchangeInternal(symAlg, keyExchangeExportMethod);
}
if (keyExchangeAlgorithm is Gost_28147_89_SymmetricAlgorithmBase symAlgBase)
{
using (var gostKeyExchangeAlgorithm = new Gost_28147_89_SymmetricAlgorithm(symAlgBase.ProviderType))
{
return gostKeyExchangeAlgorithm.EncodePrivateKey(symAlgBase, keyExchangeExportMethod);
}
}
throw ExceptionUtility.Argument(nameof(keyExchangeAlgorithm), Resources.RequiredGost28147);
}
[SecurityCritical]
private byte[] EncodeKeyExchangeInternal(Gost_28147_89_SymmetricAlgorithm keyExchangeAlgorithm, GostKeyExchangeExportMethod keyExchangeExportMethod)
{
switch (keyExchangeExportMethod)
{
case GostKeyExchangeExportMethod.GostKeyExport:
return EncodeKeyExchangeInternal(keyExchangeAlgorithm, Constants.CALG_SIMPLE_EXPORT);
case GostKeyExchangeExportMethod.CryptoProKeyExport:
return EncodeKeyExchangeInternal(keyExchangeAlgorithm, Constants.CALG_PRO_EXPORT);
}
throw ExceptionUtility.ArgumentOutOfRange(nameof(keyExchangeExportMethod));
}
[SecurityCritical]
private byte[] EncodeKeyExchangeInternal(Gost_28147_89_SymmetricAlgorithm keyExchangeAlgorithm, int keyExchangeExportAlgId)
{
Gost_28147_89_KeyExchangeInfo keyExchangeInfo;
SafeKeyHandleImpl keyExchangeHandle = null;
try
{
var importedKeyBytes = CryptoApiHelper.EncodePublicBlob(_keyExchangeParameters, _keySize, _signatureAlgId);
CryptoApiHelper.ImportCspBlob(importedKeyBytes, _provHandle, _keyHandle, out keyExchangeHandle);
CryptoApiHelper.SetKeyExchangeExportAlgId(ProviderType, keyExchangeHandle, keyExchangeExportAlgId);
var symKeyHandle = keyExchangeAlgorithm.GetSafeHandle();
keyExchangeInfo = CryptoApiHelper.ExportKeyExchange(symKeyHandle, keyExchangeHandle);
}
finally
{
keyExchangeHandle.TryDispose();
}
return keyExchangeInfo.Encode();
}
/// <inheritdoc />
[SecuritySafeCritical]
public override SymmetricAlgorithm DecodeKeyExchange(byte[] encodedKeyExchangeData, GostKeyExchangeExportMethod keyExchangeExportMethod)
{
switch (keyExchangeExportMethod)
{
case GostKeyExchangeExportMethod.GostKeyExport:
return DecodeKeyExchangeInternal(encodedKeyExchangeData, Constants.CALG_SIMPLE_EXPORT);
case GostKeyExchangeExportMethod.CryptoProKeyExport:
return DecodeKeyExchangeInternal(encodedKeyExchangeData, Constants.CALG_PRO_EXPORT);
}
throw ExceptionUtility.ArgumentOutOfRange(nameof(keyExchangeExportMethod));
}
[SecurityCritical]
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);
}
/// <inheritdoc />
[SecuritySafeCritical]
protected override void Dispose(bool disposing)
{
_keyHandle.TryDispose();
_provHandle.TryDispose();
base.Dispose(disposing);
}
}
}

View File

@ -0,0 +1,104 @@
using GostCryptography.Asn1.Gost.Gost_R3410;
using GostCryptography.Base;
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_KeyExchangeDeformatter<TKey, TKeyParams, TKeyAlgorithm> : GostKeyExchangeDeformatter
where TKey : Gost_R3410_KeyExchange, new()
where TKeyParams : Gost_R3410_KeyExchangeParams
where TKeyAlgorithm : Gost_R3410_KeyExchangeAlgorithm
{
/// <summary>
/// Конструктор
/// </summary>
protected Gost_R3410_KeyExchangeDeformatter()
{
}
/// <summary>
/// Конструктор
/// </summary>
/// <param name="privateKey">Секретный ключ для расшифровки общего секретного ключа</param>
/// <exception cref="ArgumentOutOfRangeException"></exception>
/// <exception cref="ArgumentNullException"></exception>
protected Gost_R3410_KeyExchangeDeformatter(AsymmetricAlgorithm privateKey)
{
SetKey(privateKey);
}
private Gost_R3410_AsymmetricAlgorithmBase<TKeyParams, TKeyAlgorithm> _privateKey;
/// <inheritdoc />
public override string Parameters
{
get
{
return null;
}
set
{
}
}
/// <inheritdoc />
public override void SetKey(AsymmetricAlgorithm privateKey)
{
if (privateKey == null)
{
throw ExceptionUtility.ArgumentNull(nameof(privateKey));
}
if (!(privateKey is Gost_R3410_AsymmetricAlgorithmBase<TKeyParams, TKeyAlgorithm> gostPublicKey))
{
throw ExceptionUtility.ArgumentOutOfRange(nameof(privateKey), Resources.ShouldSupportGost3410);
}
_privateKey = gostPublicKey;
}
/// <inheritdoc />
public override byte[] DecryptKeyExchange(byte[] encryptedKeyExchangeData)
{
var symmetricAlgorithm = DecryptKeyExchangeAlgorithm(encryptedKeyExchangeData);
return symmetricAlgorithm.Key;
}
/// <inheritdoc />
public override SymmetricAlgorithm DecryptKeyExchangeAlgorithm(byte[] encryptedKeyExchangeData)
{
if (encryptedKeyExchangeData == null)
{
throw ExceptionUtility.ArgumentNull(nameof(encryptedKeyExchangeData));
}
var keyExchange = new TKey();
keyExchange.Decode(encryptedKeyExchangeData);
return DecryptKeyExchangeAlgorithm(keyExchange);
}
private SymmetricAlgorithm DecryptKeyExchangeAlgorithm(TKey encryptedKeyExchangeInfo)
{
if (encryptedKeyExchangeInfo == null)
{
throw ExceptionUtility.ArgumentNull(nameof(encryptedKeyExchangeInfo));
}
var keyExchangeParameters = (TKeyParams)encryptedKeyExchangeInfo.TransportParameters;
var keyExchangeAlg = _privateKey.CreateKeyExchange(keyExchangeParameters);
var encodedKeyExchangeInfo = encryptedKeyExchangeInfo.SessionEncryptedKey.Encode();
return keyExchangeAlg.DecodeKeyExchange(encodedKeyExchangeInfo, GostKeyExchangeExportMethod.CryptoProKeyExport);
}
}
}

View File

@ -0,0 +1,162 @@
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);
}
}

View File

@ -0,0 +1,201 @@
using GostCryptography.Asn1.Gost.Gost_R3410;
using GostCryptography.Properties;
using System;
using System.Security;
using System.Text;
namespace GostCryptography.Gost_R3410
{
/// <summary>
/// Базовый класс XML-сериализатора параметров ключа цифровой подписи ГОСТ Р 34.10
/// </summary>
/// <typeparam name="TKeyParams">Параметры ключа цифровой подписи ГОСТ Р 34.10</typeparam>
public abstract class Gost_R3410_KeyExchangeXmlSerializer<TKeyParams> where TKeyParams : Gost_R3410_KeyExchangeParams
{
private const string OidPrefix = "urn:oid:";
private const string PublicKeyParametersTag = "PublicKeyParameters";
private const string PublicKeyParamSetTag = "publicKeyParamSet";
private const string DigestParamSetTag = "digestParamSet";
private const string EncryptionParamSetTag = "encryptionParamSet";
private const string PublicKeyTag = "PublicKey";
private const string PrivateKeyTag = "PrivateKey";
private readonly string _keyValueTag;
/// <summary>
/// Создает новый экземпляр данного класса
/// </summary>
/// <param name="keyValueTag">Имя тега с информацией о параметрах ключа</param>
protected Gost_R3410_KeyExchangeXmlSerializer(string keyValueTag)
{
_keyValueTag = keyValueTag;
}
/// <summary>
/// Возвращает XML с параметрами ключа
/// </summary>
public string Serialize(TKeyParams parameters)
{
var builder = new StringBuilder().AppendFormat("<{0}>", _keyValueTag);
if ((parameters.DigestParamSet != null) || (parameters.EncryptionParamSet != null) || (parameters.PublicKeyParamSet != null))
{
builder.AppendFormat("<{0}>", PublicKeyParametersTag);
builder.AppendFormat("<{0}>{1}{2}</{0}>", PublicKeyParamSetTag, OidPrefix, parameters.PublicKeyParamSet);
builder.AppendFormat("<{0}>{1}{2}</{0}>", DigestParamSetTag, OidPrefix, parameters.DigestParamSet);
if (parameters.EncryptionParamSet != null)
{
builder.AppendFormat("<{0}>{1}{2}</{0}>", EncryptionParamSetTag, OidPrefix, parameters.EncryptionParamSet);
}
builder.AppendFormat("</{0}>", PublicKeyParametersTag);
}
builder.AppendFormat("<{0}>{1}</{0}>", PublicKeyTag, Convert.ToBase64String(parameters.PublicKey));
if (parameters.PrivateKey != null)
{
builder.AppendFormat("<{0}>{1}</{0}>", PrivateKeyTag, Convert.ToBase64String(parameters.PublicKey));
}
builder.AppendFormat("</{0}>", _keyValueTag);
return builder.ToString();
}
/// <summary>
/// Возвращает параметры ключа на основе XML
/// </summary>
public TKeyParams Deserialize(string keyParametersXml, TKeyParams parameters)
{
if (string.IsNullOrEmpty(keyParametersXml))
{
throw ExceptionUtility.ArgumentNull(nameof(keyParametersXml));
}
var keyValue = SecurityElement.FromString(keyParametersXml);
if (keyValue == null)
{
throw ExceptionUtility.CryptographicException(Resources.InvalidFromXmlString, _keyValueTag);
}
keyValue = SelectChildElement(keyValue, _keyValueTag) ?? keyValue;
var publicKeyParameters = SelectChildElement(keyValue, PublicKeyParametersTag);
if (publicKeyParameters != null)
{
var publicKeyParamSet = RemoveWhiteSpaces(SelectChildElementText(publicKeyParameters, PublicKeyParamSetTag, false));
if (!publicKeyParamSet.StartsWith(OidPrefix, StringComparison.OrdinalIgnoreCase))
{
throw ExceptionUtility.CryptographicException(Resources.InvalidFromXmlString, PublicKeyParamSetTag);
}
parameters.PublicKeyParamSet = publicKeyParamSet.Substring(OidPrefix.Length);
var digestParamSet = RemoveWhiteSpaces(SelectChildElementText(publicKeyParameters, DigestParamSetTag, false));
if (!digestParamSet.StartsWith(OidPrefix, StringComparison.OrdinalIgnoreCase))
{
throw ExceptionUtility.CryptographicException(Resources.InvalidFromXmlString, DigestParamSetTag);
}
parameters.DigestParamSet = digestParamSet.Substring(OidPrefix.Length);
var encryptionParamSet = SelectChildElementText(publicKeyParameters, EncryptionParamSetTag, true);
if (!string.IsNullOrEmpty(encryptionParamSet))
{
encryptionParamSet = RemoveWhiteSpaces(encryptionParamSet);
if (!encryptionParamSet.StartsWith(OidPrefix, StringComparison.OrdinalIgnoreCase))
{
throw ExceptionUtility.CryptographicException(Resources.InvalidFromXmlString, EncryptionParamSetTag);
}
parameters.EncryptionParamSet = encryptionParamSet.Substring(OidPrefix.Length);
}
}
var publicKey = SelectChildElementText(keyValue, PublicKeyTag, false);
parameters.PublicKey = Convert.FromBase64String(RemoveWhiteSpaces(publicKey));
var privateKey = SelectChildElementText(keyValue, PrivateKeyTag, true);
if (privateKey != null)
{
parameters.PrivateKey = Convert.FromBase64String(RemoveWhiteSpaces(privateKey));
}
return parameters;
}
private static string SelectChildElementText(SecurityElement element, string childName, bool canNull)
{
string text = null;
var child = SelectChildElement(element, childName);
if (child != null && (child.Children == null || child.Children.Count == 0))
{
text = child.Text;
}
if (string.IsNullOrEmpty(text) && !canNull)
{
throw ExceptionUtility.CryptographicException(Resources.InvalidFromXmlString, childName);
}
return text;
}
private static SecurityElement SelectChildElement(SecurityElement element, string childName)
{
var children = element.Children;
if (children != null)
{
foreach (SecurityElement child in children)
{
if (string.Equals(child.Tag, childName, StringComparison.OrdinalIgnoreCase)
|| child.Tag.EndsWith(":" + childName, StringComparison.OrdinalIgnoreCase))
{
return child;
}
}
}
return null;
}
private static string RemoveWhiteSpaces(string value)
{
var length = value.Length;
var countWhiteSpace = 0;
for (var i = 0; i < length; ++i)
{
if (char.IsWhiteSpace(value[i]))
{
++countWhiteSpace;
}
}
var valueWithoutWhiteSpace = new char[length - countWhiteSpace];
for (int i = 0, j = 0; i < length; ++i)
{
if (!char.IsWhiteSpace(value[i]))
{
valueWithoutWhiteSpace[j++] = value[i];
}
}
return new string(valueWithoutWhiteSpace);
}
}
}