├── Source ├── GostCryptography │ ├── Asn1 │ │ ├── NullParams.cs │ │ ├── Ber │ │ │ ├── Asn1Status.cs │ │ │ ├── IntHolder.cs │ │ │ ├── IAsn1TaggedEventHandler.cs │ │ │ ├── Asn1CerInputStream.cs │ │ │ ├── IAsn1InputStream.cs │ │ │ ├── IAsn1NamedEventHandler.cs │ │ │ ├── Asn1DerDecodeBuffer.cs │ │ │ ├── Asn1DerEncodeBuffer.cs │ │ │ ├── IAsn1Type.cs │ │ │ ├── Asn18BitCharString.cs │ │ │ ├── Asn1VarWidthCharString.cs │ │ │ ├── Asn1MessageBuffer.cs │ │ │ ├── Asn1ChoiceExt.cs │ │ │ ├── Asn1CharSet.cs │ │ │ ├── Asn1BerInputStream.cs │ │ │ ├── Asn1DerInputStream.cs │ │ │ ├── Asn1Ia5String.cs │ │ │ ├── Asn1T61String.cs │ │ │ ├── Asn1NumericString.cs │ │ │ ├── Asn1VisibleString.cs │ │ │ ├── Asn1GeneralString.cs │ │ │ ├── Asn1GraphicString.cs │ │ │ ├── Asn1VideotexString.cs │ │ │ ├── Asn1PrintableString.cs │ │ │ ├── Asn1ObjectDescriptor.cs │ │ │ ├── Asn1CharRange.cs │ │ │ ├── Asn1Choice.cs │ │ │ ├── Asn1Null.cs │ │ │ ├── Asn1TraceHandler.cs │ │ │ ├── Asn1DiscreteCharSet.cs │ │ │ ├── Asn1RelativeOid.cs │ │ │ ├── Asn1Enumerated.cs │ │ │ ├── Asn1OutputStream.cs │ │ │ ├── Asn1OpenExt.cs │ │ │ ├── Asn1BerDecodeContext.cs │ │ │ ├── Asn1EncodeBuffer.cs │ │ │ ├── Asn1Integer.cs │ │ │ ├── Asn1Boolean.cs │ │ │ ├── Asn1OpenType.cs │ │ │ ├── Asn1Utf8String.cs │ │ │ └── Asn1Tag.cs │ │ ├── Gost │ │ │ ├── Gost_R3411 │ │ │ │ ├── Gost_R3411_DigestParams.cs │ │ │ │ └── Gost_R3411_DigestParamsType.cs │ │ │ ├── Gost_R3410_94 │ │ │ │ ├── Gost_R3411_94_DigestParams.cs │ │ │ │ ├── Gost_R3410_94_PublicKeyParams.cs │ │ │ │ ├── Gost_R3410_94_PublicKey.cs │ │ │ │ ├── Gost_R3410_94_DhPublicKeyType.cs │ │ │ │ ├── Gost_R3410_94_PublicKeyType.cs │ │ │ │ ├── Gost_R3411_94_DigestParamsType.cs │ │ │ │ ├── Gost_R3410_94_KeyExchange.cs │ │ │ │ ├── Gost_R3410_94_KeyExchangeParams.cs │ │ │ │ └── Gost_R3410_94_Constants.cs │ │ │ ├── Gost_R3410_2001 │ │ │ │ ├── Gost_R3411_2001_DigestParams.cs │ │ │ │ ├── Gost_R3410_2001_PublicKeyParams.cs │ │ │ │ ├── Gost_R3410_2001_PublicKey.cs │ │ │ │ ├── Gost_R3410_2001_DhPublicKeyType.cs │ │ │ │ ├── Gost_R3410_2001_PublicKeyType.cs │ │ │ │ ├── Gost_R3411_2001_DigestParamsType.cs │ │ │ │ ├── Gost_R3410_2001_KeyExchange.cs │ │ │ │ ├── Gost_R3410_2001_KeyExchangeParams.cs │ │ │ │ └── Gost_R3410_2001_Constants.cs │ │ │ ├── Gost_R3410_2012_256 │ │ │ │ ├── Gost_R3411_2012_256_DigestParams.cs │ │ │ │ ├── Gost_R3410_2012_256_PublicKeyParams.cs │ │ │ │ ├── Gost_R3410_2012_256_PublicKey.cs │ │ │ │ ├── Gost_R3410_2012_256_DhPublicKeyType.cs │ │ │ │ ├── Gost_R3410_2012_256_PublicKeyType.cs │ │ │ │ ├── Gost_R3411_2012_256_DigestParamsType.cs │ │ │ │ ├── Gost_R3410_2012_256_KeyExchange.cs │ │ │ │ ├── Gost_R3410_2012_256_KeyExchangeParams.cs │ │ │ │ └── Gost_R3410_2012_256_Constants.cs │ │ │ ├── Gost_R3410_2012_512 │ │ │ │ ├── Gost_R3411_2012_512_DigestParams.cs │ │ │ │ ├── Gost_R3410_2012_512_PublicKeyParams.cs │ │ │ │ ├── Gost_R3410_2012_512_PublicKey.cs │ │ │ │ ├── Gost_R3410_2012_512_DhPublicKeyType.cs │ │ │ │ ├── Gost_R3410_2012_512_PublicKeyType.cs │ │ │ │ ├── Gost_R3411_2012_512_DigestParamsType.cs │ │ │ │ ├── Gost_R3410_2012_512_KeyExchange.cs │ │ │ │ ├── Gost_R3410_2012_512_KeyExchangeParams.cs │ │ │ │ └── Gost_R3410_2012_512_Constants.cs │ │ │ ├── Gost_R3410 │ │ │ │ ├── Gost_R3410_PublicKeyType.cs │ │ │ │ ├── Gost_R3410_PublicKey.cs │ │ │ │ ├── Gost_R3410_KeyTransport.cs │ │ │ │ ├── Gost_R3410_PublicKeyParams.cs │ │ │ │ └── Gost_R3410_TransportParams.cs │ │ │ ├── Gost_28147_89 │ │ │ │ ├── Gost_28147_89_Constants.cs │ │ │ │ ├── Gost_28147_89_Iv.cs │ │ │ │ ├── Gost_28147_89_Key.cs │ │ │ │ ├── Gost_28147_89_Mac.cs │ │ │ │ ├── Gost_28147_89_Params.cs │ │ │ │ ├── Gost_28147_89_KeyWrap.cs │ │ │ │ ├── Gost_28147_89_BlobParams.cs │ │ │ │ ├── Gost_28147_89_KeyWrapParams.cs │ │ │ │ └── Gost_28147_89_EncryptedKey.cs │ │ │ ├── PublicKey │ │ │ │ ├── AlgorithmId.cs │ │ │ │ └── SubjectPublicKeyInfo.cs │ │ │ └── GostAsn1Choice.cs │ │ └── OidValue.cs │ ├── Gost_28147_89 │ │ ├── Gost_28147_89_CryptoTransformMode.cs │ │ ├── Gost_28147_89_ImitHashAlgorithmBase.cs │ │ └── Gost_28147_89_SymmetricAlgorithmBase.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── Base │ │ ├── GostSignatureDescription.cs │ │ ├── IGostAlgorithm.cs │ │ ├── GostKeyExchangeExportMethod.cs │ │ ├── GostKeyExchangeFormatter.cs │ │ ├── GostKeyExchangeDeformatter.cs │ │ ├── GostPrf.cs │ │ ├── GostSymmetricAlgorithm.cs │ │ ├── GostHashAlgorithm.cs │ │ ├── GostHMAC.cs │ │ ├── GostKeyedHashAlgorithm.cs │ │ ├── GostAsymmetricAlgorithm.cs │ │ ├── GostSignatureFormatter.cs │ │ ├── GostSignatureDeformatter.cs │ │ ├── ProviderType.cs │ │ ├── GostKeyExchangeAlgorithm.cs │ │ └── GostExternalAsymmetricAlgorithm.cs │ ├── Xml │ │ ├── GetIdElementDelegate.cs │ │ ├── Gost_R3410_2001_KeyValue.cs │ │ ├── Gost_R3410_2012_256_KeyValue.cs │ │ ├── Gost_R3410_2012_512_KeyValue.cs │ │ └── GostKeyValue.cs │ ├── Gost_R3410 │ │ ├── Gost_R3410_2001_KeyExchangeXmlSerializer.cs │ │ ├── Gost_R3410_2012_256_KeyExchangeXmlSerializer.cs │ │ ├── Gost_R3410_2012_512_KeyExchangeXmlSerializer.cs │ │ ├── Gost_R3410_2001_KeyExchangeAlgorithm.cs │ │ ├── Gost_R3410_2012_256_KeyExchangeAlgorithm.cs │ │ ├── Gost_R3410_2012_512_KeyExchangeAlgorithm.cs │ │ ├── Gost_R3410_2001_KeyExchangeDeformatter.cs │ │ ├── Gost_R3410_2001_SignatureDescription.cs │ │ ├── Gost_R3410_2012_256_KeyExchangeDeformatter.cs │ │ ├── Gost_R3410_2012_512_KeyExchangeDeformatter.cs │ │ ├── Gost_R3410_2012_256_SignatureDescription.cs │ │ ├── Gost_R3410_2012_512_SignatureDescription.cs │ │ ├── Gost_R3410_2001_KeyExchangeFormatter.cs │ │ ├── Gost_R3410_2012_256_KeyExchangeFormatter.cs │ │ └── Gost_R3410_2012_512_KeyExchangeFormatter.cs │ ├── Native │ │ ├── SafeHashHandleImpl.cs │ │ ├── ISafeHandleProvider.cs │ │ ├── SafeKeyHandleImpl.cs │ │ ├── SafeStore.cs │ │ └── SafeProvHandleImpl.cs │ ├── Reflection │ │ ├── CryptographyUtils.cs │ │ ├── CspKeyContainerInfoHelper.cs │ │ └── EncryptedXmlHelper.cs │ ├── Gost_R3411 │ │ ├── Gost_R3411_2012_256_HashAlgorithm.cs │ │ ├── Gost_R3411_2012_512_HashAlgorithm.cs │ │ ├── Gost_R3411_94_PRF.cs │ │ ├── Gost_R3411_2012_256_HMAC.cs │ │ ├── Gost_R3411_2012_512_HMAC.cs │ │ ├── Gost_R3411_2012_256_PRF.cs │ │ ├── Gost_R3411_2012_512_PRF.cs │ │ ├── Gost_R3411_94_HashAlgorithm.cs │ │ ├── Gost_R3411_94_HMAC.cs │ │ └── Gost_R3411_HashAlgorithm.cs │ └── GostCryptography.csproj └── GostCryptography.Tests │ ├── Data │ ├── SignedXmlExample.xml │ ├── EncryptedXmlExample.xml │ └── SmevExample.xml │ ├── TestCertificateInfo.cs │ ├── GostCryptography.Tests.csproj │ ├── Gost_R3411 │ ├── Gost_R3411_94_HashAlgorithmTest.cs │ ├── Gost_R3411_2012_256_HashAlgorithmTest.cs │ └── Gost_R3411_2012_512_HashAlgorithmTest.cs │ ├── Pkcs │ ├── EnvelopedCmsEncryptTest.cs │ ├── SignedCmsSignTest.cs │ └── SignedCmsDetachedSignTest.cs │ ├── Sign │ ├── SignDataStreamCertificateTest.cs │ └── SignDataStreamSignatureFormatterTest.cs │ ├── Gost_28147_89 │ └── Gost_28147_89_SymmetricAlgorithmTest.cs │ └── Xml │ └── Encrypt │ └── EncryptedXmlCertificateTest.cs ├── .github └── workflows │ └── main.yml ├── LICENSE └── GostCryptography.sln /Source/GostCryptography/Asn1/NullParams.cs: -------------------------------------------------------------------------------- 1 | using GostCryptography.Asn1.Ber; 2 | 3 | namespace GostCryptography.Asn1 4 | { 5 | public sealed class NullParams : Asn1Null 6 | { 7 | } 8 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Asn1/Ber/Asn1Status.cs: -------------------------------------------------------------------------------- 1 | namespace GostCryptography.Asn1.Ber 2 | { 3 | public static class Asn1Status 4 | { 5 | public const int IndefiniteLength = -9999; 6 | } 7 | } -------------------------------------------------------------------------------- /Source/GostCryptography.Tests/Data/SignedXmlExample.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Here is some data to sign. 5 | 6 | -------------------------------------------------------------------------------- /Source/GostCryptography/Gost_28147_89/Gost_28147_89_CryptoTransformMode.cs: -------------------------------------------------------------------------------- 1 | namespace GostCryptography.Gost_28147_89 2 | { 3 | enum Gost_28147_89_CryptoTransformMode 4 | { 5 | Encrypt, 6 | Decrypt 7 | } 8 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Asn1/Gost/Gost_R3411/Gost_R3411_DigestParams.cs: -------------------------------------------------------------------------------- 1 | using GostCryptography.Asn1.Ber; 2 | 3 | namespace GostCryptography.Asn1.Gost.Gost_R3411 4 | { 5 | public abstract class Gost_R3411_DigestParams : Asn1ObjectIdentifier 6 | { 7 | } 8 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.InteropServices; 2 | using System.Security; 3 | 4 | [assembly: ComVisible(false)] 5 | [assembly: Guid("13e0930e-42fa-4821-8214-e979572a8dbe")] 6 | [assembly: AllowPartiallyTrustedCallers] -------------------------------------------------------------------------------- /Source/GostCryptography/Asn1/Gost/Gost_R3410_94/Gost_R3411_94_DigestParams.cs: -------------------------------------------------------------------------------- 1 | using GostCryptography.Asn1.Gost.Gost_R3411; 2 | 3 | namespace GostCryptography.Asn1.Gost.Gost_R3410_94 4 | { 5 | public sealed class Gost_R3411_94_DigestParams : Gost_R3411_DigestParams 6 | { 7 | } 8 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Asn1/Gost/Gost_R3410_2001/Gost_R3411_2001_DigestParams.cs: -------------------------------------------------------------------------------- 1 | using GostCryptography.Asn1.Gost.Gost_R3411; 2 | 3 | namespace GostCryptography.Asn1.Gost.Gost_R3410_2001 4 | { 5 | public sealed class Gost_R3411_2001_DigestParams : Gost_R3411_DigestParams 6 | { 7 | } 8 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Asn1/Ber/IntHolder.cs: -------------------------------------------------------------------------------- 1 | namespace GostCryptography.Asn1.Ber 2 | { 3 | public class IntHolder 4 | { 5 | public int Value; 6 | 7 | public IntHolder() 8 | { 9 | } 10 | 11 | public IntHolder(int value) 12 | { 13 | Value = value; 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Asn1/Gost/Gost_R3410_94/Gost_R3410_94_PublicKeyParams.cs: -------------------------------------------------------------------------------- 1 | using GostCryptography.Asn1.Gost.Gost_R3410; 2 | 3 | namespace GostCryptography.Asn1.Gost.Gost_R3410_94 4 | { 5 | public sealed class Gost_R3410_94_PublicKeyParams : Gost_R3410_PublicKeyParams 6 | { 7 | } 8 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Asn1/Ber/IAsn1TaggedEventHandler.cs: -------------------------------------------------------------------------------- 1 | namespace GostCryptography.Asn1.Ber 2 | { 3 | public interface IAsn1TaggedEventHandler 4 | { 5 | void Contents(byte[] data); 6 | void EndElement(Asn1Tag tag); 7 | void StartElement(Asn1Tag tag, int len, byte[] tagLenBytes); 8 | } 9 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Asn1/Gost/Gost_R3410_2001/Gost_R3410_2001_PublicKeyParams.cs: -------------------------------------------------------------------------------- 1 | using GostCryptography.Asn1.Gost.Gost_R3410; 2 | 3 | namespace GostCryptography.Asn1.Gost.Gost_R3410_2001 4 | { 5 | public sealed class Gost_R3410_2001_PublicKeyParams : Gost_R3410_PublicKeyParams 6 | { 7 | } 8 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Asn1/Ber/Asn1CerInputStream.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | 3 | namespace GostCryptography.Asn1.Ber 4 | { 5 | public class Asn1CerInputStream : Asn1BerInputStream 6 | { 7 | public Asn1CerInputStream(Stream inputStream) 8 | : base(inputStream) 9 | { 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Asn1/Ber/IAsn1InputStream.cs: -------------------------------------------------------------------------------- 1 | namespace GostCryptography.Asn1.Ber 2 | { 3 | public interface IAsn1InputStream 4 | { 5 | int Available(); 6 | void Close(); 7 | void Mark(); 8 | bool MarkSupported(); 9 | void Reset(); 10 | long Skip(long nbytes); 11 | } 12 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Asn1/Gost/Gost_R3410_2012_256/Gost_R3411_2012_256_DigestParams.cs: -------------------------------------------------------------------------------- 1 | using GostCryptography.Asn1.Gost.Gost_R3411; 2 | 3 | namespace GostCryptography.Asn1.Gost.Gost_R3410_2012_256 4 | { 5 | public sealed class Gost_R3411_2012_256_DigestParams : Gost_R3411_DigestParams 6 | { 7 | } 8 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Asn1/Gost/Gost_R3410_2012_512/Gost_R3411_2012_512_DigestParams.cs: -------------------------------------------------------------------------------- 1 | using GostCryptography.Asn1.Gost.Gost_R3411; 2 | 3 | namespace GostCryptography.Asn1.Gost.Gost_R3410_2012_512 4 | { 5 | public sealed class Gost_R3411_2012_512_DigestParams : Gost_R3411_DigestParams 6 | { 7 | } 8 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Asn1/Ber/IAsn1NamedEventHandler.cs: -------------------------------------------------------------------------------- 1 | namespace GostCryptography.Asn1.Ber 2 | { 3 | public interface IAsn1NamedEventHandler 4 | { 5 | void Characters(string svalue, short typeCode); 6 | void EndElement(string name, int index); 7 | void StartElement(string name, int index); 8 | } 9 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Asn1/Gost/Gost_R3410_2012_256/Gost_R3410_2012_256_PublicKeyParams.cs: -------------------------------------------------------------------------------- 1 | using GostCryptography.Asn1.Gost.Gost_R3410; 2 | 3 | namespace GostCryptography.Asn1.Gost.Gost_R3410_2012_256 4 | { 5 | public sealed class Gost_R3410_2012_256_PublicKeyParams : Gost_R3410_PublicKeyParams 6 | { 7 | } 8 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Asn1/Gost/Gost_R3410_2012_512/Gost_R3410_2012_512_PublicKeyParams.cs: -------------------------------------------------------------------------------- 1 | using GostCryptography.Asn1.Gost.Gost_R3410; 2 | 3 | namespace GostCryptography.Asn1.Gost.Gost_R3410_2012_512 4 | { 5 | public sealed class Gost_R3410_2012_512_PublicKeyParams : Gost_R3410_PublicKeyParams 6 | { 7 | } 8 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Asn1/Gost/Gost_R3410/Gost_R3410_PublicKeyType.cs: -------------------------------------------------------------------------------- 1 | namespace GostCryptography.Asn1.Gost.Gost_R3410 2 | { 3 | public abstract class Gost_R3410_PublicKeyType : GostAsn1Choice 4 | { 5 | protected override short TagForm => 0x20; 6 | 7 | protected override int TagIdCode => SequenceTypeCode; 8 | } 9 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Base/GostSignatureDescription.cs: -------------------------------------------------------------------------------- 1 | using System.Security.Cryptography; 2 | 3 | namespace GostCryptography.Base 4 | { 5 | /// 6 | /// Информация о свойствах цифровой подписи ГОСТ. 7 | /// 8 | public abstract class GostSignatureDescription : SignatureDescription 9 | { 10 | } 11 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Asn1/Gost/Gost_R3411/Gost_R3411_DigestParamsType.cs: -------------------------------------------------------------------------------- 1 | namespace GostCryptography.Asn1.Gost.Gost_R3411 2 | { 3 | public abstract class Gost_R3411_DigestParamsType : GostAsn1Choice 4 | { 5 | protected override short TagForm => 0x00; 6 | 7 | protected override int TagIdCode => ObjectIdentifierTypeCode; 8 | } 9 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Asn1/Gost/Gost_28147_89/Gost_28147_89_Constants.cs: -------------------------------------------------------------------------------- 1 | namespace GostCryptography.Asn1.Gost.Gost_28147_89 2 | { 3 | public static class Gost_28147_89_Constants 4 | { 5 | /// 6 | /// Алгоритм шифрования ГОСТ 28147-89. 7 | /// 8 | public static readonly OidValue EncryptAlgorithm = OidValue.FromString("1.2.643.2.2.21"); 9 | } 10 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Asn1/Ber/Asn1DerDecodeBuffer.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | 3 | namespace GostCryptography.Asn1.Ber 4 | { 5 | public class Asn1DerDecodeBuffer : Asn1BerDecodeBuffer 6 | { 7 | public Asn1DerDecodeBuffer(byte[] msgdata) 8 | : base(msgdata) 9 | { 10 | } 11 | 12 | public Asn1DerDecodeBuffer(Stream inputStream) 13 | : base(inputStream) 14 | { 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Asn1/Gost/Gost_R3410_94/Gost_R3410_94_PublicKey.cs: -------------------------------------------------------------------------------- 1 | using GostCryptography.Asn1.Gost.Gost_R3410; 2 | 3 | namespace GostCryptography.Asn1.Gost.Gost_R3410_94 4 | { 5 | /// 6 | public sealed class Gost_R3410_94_PublicKey : Gost_R3410_PublicKey 7 | { 8 | /// 9 | public Gost_R3410_94_PublicKey() : base(64) 10 | { 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Asn1/Gost/Gost_R3410_2001/Gost_R3410_2001_PublicKey.cs: -------------------------------------------------------------------------------- 1 | using GostCryptography.Asn1.Gost.Gost_R3410; 2 | 3 | namespace GostCryptography.Asn1.Gost.Gost_R3410_2001 4 | { 5 | /// 6 | public sealed class Gost_R3410_2001_PublicKey : Gost_R3410_PublicKey 7 | { 8 | /// 9 | public Gost_R3410_2001_PublicKey() : base(64) 10 | { 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Asn1/Ber/Asn1DerEncodeBuffer.cs: -------------------------------------------------------------------------------- 1 | namespace GostCryptography.Asn1.Ber 2 | { 3 | public class Asn1DerEncodeBuffer : Asn1BerEncodeBuffer 4 | { 5 | public Asn1DerEncodeBuffer() 6 | { 7 | ByteIndex = SizeIncrement - 1; 8 | } 9 | 10 | public Asn1DerEncodeBuffer(int sizeIncrement) 11 | : base(sizeIncrement) 12 | { 13 | ByteIndex = SizeIncrement - 1; 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Asn1/Gost/Gost_R3410_2012_256/Gost_R3410_2012_256_PublicKey.cs: -------------------------------------------------------------------------------- 1 | using GostCryptography.Asn1.Gost.Gost_R3410; 2 | 3 | namespace GostCryptography.Asn1.Gost.Gost_R3410_2012_256 4 | { 5 | /// 6 | public sealed class Gost_R3410_2012_256_PublicKey : Gost_R3410_PublicKey 7 | { 8 | /// 9 | public Gost_R3410_2012_256_PublicKey() : base(64) 10 | { 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Asn1/Gost/Gost_R3410_2012_512/Gost_R3410_2012_512_PublicKey.cs: -------------------------------------------------------------------------------- 1 | using GostCryptography.Asn1.Gost.Gost_R3410; 2 | 3 | namespace GostCryptography.Asn1.Gost.Gost_R3410_2012_512 4 | { 5 | /// 6 | public sealed class Gost_R3410_2012_512_PublicKey : Gost_R3410_PublicKey 7 | { 8 | /// 9 | public Gost_R3410_2012_512_PublicKey() : base(128) 10 | { 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Asn1/Gost/PublicKey/AlgorithmId.cs: -------------------------------------------------------------------------------- 1 | using GostCryptography.Asn1.Ber; 2 | 3 | namespace GostCryptography.Asn1.Gost.PublicKey 4 | { 5 | public sealed class AlgorithmId 6 | { 7 | public AlgorithmId(Asn1ObjectIdentifier id, Asn1Type type) 8 | { 9 | Id = id; 10 | Type = type; 11 | } 12 | 13 | 14 | public Asn1ObjectIdentifier Id { get; } 15 | 16 | public Asn1Type Type { get; } 17 | } 18 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Asn1/Gost/Gost_R3410_94/Gost_R3410_94_DhPublicKeyType.cs: -------------------------------------------------------------------------------- 1 | using GostCryptography.Asn1.Ber; 2 | using GostCryptography.Asn1.Gost.Gost_R3410; 3 | 4 | namespace GostCryptography.Asn1.Gost.Gost_R3410_94 5 | { 6 | public sealed class Gost_R3410_94_DhPublicKeyType : Gost_R3410_PublicKeyType 7 | { 8 | protected override Asn1Type CreateParams() 9 | { 10 | return new Gost_R3410_94_PublicKeyParams(); 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Asn1/Gost/Gost_R3410_94/Gost_R3410_94_PublicKeyType.cs: -------------------------------------------------------------------------------- 1 | using GostCryptography.Asn1.Ber; 2 | using GostCryptography.Asn1.Gost.Gost_R3410; 3 | 4 | namespace GostCryptography.Asn1.Gost.Gost_R3410_94 5 | { 6 | public sealed class Gost_R3410_94_PublicKeyType : Gost_R3410_PublicKeyType 7 | { 8 | protected override Asn1Type CreateParams() 9 | { 10 | return new Gost_R3410_94_PublicKeyParams(); 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Asn1/Ber/IAsn1Type.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | 3 | namespace GostCryptography.Asn1.Ber 4 | { 5 | public interface IAsn1Type 6 | { 7 | void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength); 8 | int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging); 9 | void Encode(Asn1BerOutputStream outs, bool explicitTagging); 10 | void Print(TextWriter outs, string varName, int level); 11 | } 12 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Asn1/Gost/Gost_R3410_94/Gost_R3411_94_DigestParamsType.cs: -------------------------------------------------------------------------------- 1 | using GostCryptography.Asn1.Ber; 2 | using GostCryptography.Asn1.Gost.Gost_R3411; 3 | 4 | namespace GostCryptography.Asn1.Gost.Gost_R3410_94 5 | { 6 | public sealed class Gost_R3411_94_DigestParamsType : Gost_R3411_DigestParamsType 7 | { 8 | protected override Asn1Type CreateParams() 9 | { 10 | return new Gost_R3411_94_DigestParams(); 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /Source/GostCryptography.Tests/Data/EncryptedXmlExample.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Here is public data. 5 | 6 | 7 | Here is private data. 8 | 9 | 10 | Here is private data. 11 | 12 | 13 | Here is private data. 14 | 15 | -------------------------------------------------------------------------------- /Source/GostCryptography/Asn1/Gost/Gost_R3410_2001/Gost_R3410_2001_DhPublicKeyType.cs: -------------------------------------------------------------------------------- 1 | using GostCryptography.Asn1.Ber; 2 | using GostCryptography.Asn1.Gost.Gost_R3410; 3 | 4 | namespace GostCryptography.Asn1.Gost.Gost_R3410_2001 5 | { 6 | public sealed class Gost_R3410_2001_DhPublicKeyType : Gost_R3410_PublicKeyType 7 | { 8 | protected override Asn1Type CreateParams() 9 | { 10 | return new Gost_R3410_2001_PublicKeyParams(); 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Asn1/Gost/Gost_R3410_2001/Gost_R3410_2001_PublicKeyType.cs: -------------------------------------------------------------------------------- 1 | using GostCryptography.Asn1.Ber; 2 | using GostCryptography.Asn1.Gost.Gost_R3410; 3 | 4 | namespace GostCryptography.Asn1.Gost.Gost_R3410_2001 5 | { 6 | public sealed class Gost_R3410_2001_PublicKeyType : Gost_R3410_PublicKeyType 7 | { 8 | protected override Asn1Type CreateParams() 9 | { 10 | return new Gost_R3410_2001_PublicKeyParams(); 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Asn1/Gost/Gost_R3410_2001/Gost_R3411_2001_DigestParamsType.cs: -------------------------------------------------------------------------------- 1 | using GostCryptography.Asn1.Ber; 2 | using GostCryptography.Asn1.Gost.Gost_R3411; 3 | 4 | namespace GostCryptography.Asn1.Gost.Gost_R3410_2001 5 | { 6 | public sealed class Gost_R3411_2001_DigestParamsType : Gost_R3411_DigestParamsType 7 | { 8 | protected override Asn1Type CreateParams() 9 | { 10 | return new Gost_R3411_2001_DigestParams(); 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Base/IGostAlgorithm.cs: -------------------------------------------------------------------------------- 1 | namespace GostCryptography.Base 2 | { 3 | /// 4 | /// Алгоритм ГОСТ. 5 | /// 6 | public interface IGostAlgorithm 7 | { 8 | /// 9 | /// Тип криптографического провайдера. 10 | /// 11 | ProviderType ProviderType { get; } 12 | 13 | /// 14 | /// Наименование криптографического алгоритма. 15 | /// 16 | string AlgorithmName { get; } 17 | } 18 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Xml/GetIdElementDelegate.cs: -------------------------------------------------------------------------------- 1 | using System.Xml; 2 | 3 | namespace GostCryptography.Xml 4 | { 5 | /// 6 | /// Возвращает XML-элемент с указанным идентификатором. 7 | /// 8 | /// Документ для поиска идентификатора элемента. 9 | /// Значение идентификатора элемента. 10 | public delegate XmlElement GetIdElementDelegate(XmlDocument document, string idValue); 11 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Asn1/Gost/Gost_R3410_2012_256/Gost_R3410_2012_256_DhPublicKeyType.cs: -------------------------------------------------------------------------------- 1 | using GostCryptography.Asn1.Ber; 2 | using GostCryptography.Asn1.Gost.Gost_R3410; 3 | 4 | namespace GostCryptography.Asn1.Gost.Gost_R3410_2012_256 5 | { 6 | public sealed class Gost_R3410_2012_256_DhPublicKeyType : Gost_R3410_PublicKeyType 7 | { 8 | protected override Asn1Type CreateParams() 9 | { 10 | return new Gost_R3410_2012_256_PublicKeyParams(); 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Asn1/Gost/Gost_R3410_2012_256/Gost_R3410_2012_256_PublicKeyType.cs: -------------------------------------------------------------------------------- 1 | using GostCryptography.Asn1.Ber; 2 | using GostCryptography.Asn1.Gost.Gost_R3410; 3 | 4 | namespace GostCryptography.Asn1.Gost.Gost_R3410_2012_256 5 | { 6 | public sealed class Gost_R3410_2012_256_PublicKeyType : Gost_R3410_PublicKeyType 7 | { 8 | protected override Asn1Type CreateParams() 9 | { 10 | return new Gost_R3410_2012_256_PublicKeyParams(); 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Asn1/Gost/Gost_R3410_2012_512/Gost_R3410_2012_512_DhPublicKeyType.cs: -------------------------------------------------------------------------------- 1 | using GostCryptography.Asn1.Ber; 2 | using GostCryptography.Asn1.Gost.Gost_R3410; 3 | 4 | namespace GostCryptography.Asn1.Gost.Gost_R3410_2012_512 5 | { 6 | public sealed class Gost_R3410_2012_512_DhPublicKeyType : Gost_R3410_PublicKeyType 7 | { 8 | protected override Asn1Type CreateParams() 9 | { 10 | return new Gost_R3410_2012_512_PublicKeyParams(); 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Asn1/Gost/Gost_R3410_2012_512/Gost_R3410_2012_512_PublicKeyType.cs: -------------------------------------------------------------------------------- 1 | using GostCryptography.Asn1.Ber; 2 | using GostCryptography.Asn1.Gost.Gost_R3410; 3 | 4 | namespace GostCryptography.Asn1.Gost.Gost_R3410_2012_512 5 | { 6 | public sealed class Gost_R3410_2012_512_PublicKeyType : Gost_R3410_PublicKeyType 7 | { 8 | protected override Asn1Type CreateParams() 9 | { 10 | return new Gost_R3410_2012_512_PublicKeyParams(); 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Asn1/Gost/Gost_R3410_2012_256/Gost_R3411_2012_256_DigestParamsType.cs: -------------------------------------------------------------------------------- 1 | using GostCryptography.Asn1.Ber; 2 | using GostCryptography.Asn1.Gost.Gost_R3411; 3 | 4 | namespace GostCryptography.Asn1.Gost.Gost_R3410_2012_256 5 | { 6 | public sealed class Gost_R3411_2012_256_DigestParamsType : Gost_R3411_DigestParamsType 7 | { 8 | protected override Asn1Type CreateParams() 9 | { 10 | return new Gost_R3411_2012_256_DigestParams(); 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Asn1/Gost/Gost_R3410_2012_512/Gost_R3411_2012_512_DigestParamsType.cs: -------------------------------------------------------------------------------- 1 | using GostCryptography.Asn1.Ber; 2 | using GostCryptography.Asn1.Gost.Gost_R3411; 3 | 4 | namespace GostCryptography.Asn1.Gost.Gost_R3410_2012_512 5 | { 6 | public sealed class Gost_R3411_2012_512_DigestParamsType : Gost_R3411_DigestParamsType 7 | { 8 | protected override Asn1Type CreateParams() 9 | { 10 | return new Gost_R3411_2012_512_DigestParams(); 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Base/GostKeyExchangeExportMethod.cs: -------------------------------------------------------------------------------- 1 | namespace GostCryptography.Base 2 | { 3 | /// 4 | /// Алгоритм экспорта общего секретного ключа ГОСТ. 5 | /// 6 | public enum GostKeyExchangeExportMethod 7 | { 8 | /// 9 | /// Простой экспорт ключа по ГОСТ 28147-89. 10 | /// 11 | GostKeyExport, 12 | 13 | /// 14 | /// Защищённый экспорт ключа по алгоритму КриптоПро. 15 | /// 16 | CryptoProKeyExport 17 | } 18 | } -------------------------------------------------------------------------------- /Source/GostCryptography.Tests/TestCertificateInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Security.Cryptography.X509Certificates; 2 | 3 | namespace GostCryptography.Tests 4 | { 5 | public class TestCertificateInfo 6 | { 7 | public TestCertificateInfo(string name, X509Certificate2 certificate) 8 | { 9 | Name = name; 10 | Certificate = certificate; 11 | } 12 | 13 | 14 | public string Name { get; } 15 | 16 | public X509Certificate2 Certificate { get; } 17 | 18 | 19 | public override string ToString() => Name; 20 | } 21 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Asn1/Ber/Asn18BitCharString.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace GostCryptography.Asn1.Ber 4 | { 5 | [Serializable] 6 | public abstract class Asn18BitCharString : Asn1CharString 7 | { 8 | public const int BitsPerCharA = 8; 9 | public const int BitsPerCharU = 7; 10 | 11 | protected internal Asn18BitCharString(short typeCode) 12 | : base(typeCode) 13 | { 14 | } 15 | 16 | protected internal Asn18BitCharString(string data, short typeCode) 17 | : base(data, typeCode) 18 | { 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Asn1/Ber/Asn1VarWidthCharString.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace GostCryptography.Asn1.Ber 4 | { 5 | [Serializable] 6 | public abstract class Asn1VarWidthCharString : Asn1CharString 7 | { 8 | public const int BitsPerCharA = 8; 9 | public const int BitsPerCharU = 8; 10 | 11 | protected internal Asn1VarWidthCharString(short typeCode) 12 | : base(typeCode) 13 | { 14 | } 15 | 16 | protected internal Asn1VarWidthCharString(string data, short typeCode) 17 | : base(data, typeCode) 18 | { 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Asn1/Ber/Asn1MessageBuffer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | 4 | namespace GostCryptography.Asn1.Ber 5 | { 6 | public abstract class Asn1MessageBuffer 7 | { 8 | public abstract Stream GetInputStream(); 9 | 10 | public static void HexDump(Stream ins) 11 | { 12 | var outs = new StreamWriter(Console.OpenStandardOutput(), Console.Out.Encoding) 13 | { 14 | AutoFlush = true 15 | }; 16 | 17 | HexDump(ins, outs); 18 | } 19 | 20 | public static void HexDump(Stream ins, StreamWriter outs) 21 | { 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Asn1/Ber/Asn1ChoiceExt.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace GostCryptography.Asn1.Ber 4 | { 5 | [Serializable] 6 | public class Asn1ChoiceExt : Asn1OpenType 7 | { 8 | public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength) 9 | { 10 | base.Decode(buffer, false, 0); 11 | } 12 | 13 | public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging) 14 | { 15 | return base.Encode(buffer, false); 16 | } 17 | 18 | public override void Encode(Asn1BerOutputStream outs, bool explicitTagging) 19 | { 20 | base.Encode(outs, false); 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Base/GostKeyExchangeFormatter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Security.Cryptography; 3 | 4 | namespace GostCryptography.Base 5 | { 6 | /// 7 | /// Базовый класс для шифрования общего секретного ключа по ГОСТ. 8 | /// 9 | public abstract class GostKeyExchangeFormatter : AsymmetricKeyExchangeFormatter 10 | { 11 | /// 12 | /// Шифрует общий секретный ключ. 13 | /// 14 | /// Алгоритм шифрования общего секретного ключа. 15 | /// 16 | public abstract byte[] CreateKeyExchangeData(SymmetricAlgorithm keyExchangeAlgorithm); 17 | } 18 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Asn1/Gost/Gost_R3410_94/Gost_R3410_94_KeyExchange.cs: -------------------------------------------------------------------------------- 1 | using GostCryptography.Asn1.Gost.Gost_R3410; 2 | 3 | namespace GostCryptography.Asn1.Gost.Gost_R3410_94 4 | { 5 | /// 6 | public sealed class Gost_R3410_94_KeyExchange : Gost_R3410_KeyExchange 7 | { 8 | /// 9 | protected override OidValue KeyAlgorithm => Gost_R3410_94_Constants.KeyAlgorithm; 10 | 11 | /// 12 | protected override Gost_R3410_PublicKeyParams CreatePublicKeyParams() => new Gost_R3410_94_PublicKeyParams(); 13 | 14 | /// 15 | protected override Gost_R3410_KeyExchangeParams CreateKeyExchangeParams() => new Gost_R3410_94_KeyExchangeParams(); 16 | } 17 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Base/GostKeyExchangeDeformatter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Security.Cryptography; 3 | 4 | namespace GostCryptography.Base 5 | { 6 | /// 7 | /// Базовый класс для дешифрования общего секретного ключа по ГОСТ. 8 | /// 9 | public abstract class GostKeyExchangeDeformatter : AsymmetricKeyExchangeDeformatter 10 | { 11 | /// 12 | /// Дешифрует общий секретный ключ. 13 | /// 14 | /// Зашифрованный общий секретный ключ. 15 | /// 16 | public abstract SymmetricAlgorithm DecryptKeyExchangeAlgorithm(byte[] encryptedKeyExchangeData); 17 | } 18 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Asn1/Gost/Gost_R3410_2001/Gost_R3410_2001_KeyExchange.cs: -------------------------------------------------------------------------------- 1 | using GostCryptography.Asn1.Gost.Gost_R3410; 2 | 3 | namespace GostCryptography.Asn1.Gost.Gost_R3410_2001 4 | { 5 | /// 6 | public sealed class Gost_R3410_2001_KeyExchange : Gost_R3410_KeyExchange 7 | { 8 | /// 9 | protected override OidValue KeyAlgorithm => Gost_R3410_2001_Constants.KeyAlgorithm; 10 | 11 | /// 12 | protected override Gost_R3410_PublicKeyParams CreatePublicKeyParams() => new Gost_R3410_2001_PublicKeyParams(); 13 | 14 | /// 15 | protected override Gost_R3410_KeyExchangeParams CreateKeyExchangeParams() => new Gost_R3410_2001_KeyExchangeParams(); 16 | } 17 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Asn1/Gost/Gost_R3410_2012_256/Gost_R3410_2012_256_KeyExchange.cs: -------------------------------------------------------------------------------- 1 | using GostCryptography.Asn1.Gost.Gost_R3410; 2 | 3 | namespace GostCryptography.Asn1.Gost.Gost_R3410_2012_256 4 | { 5 | /// 6 | public sealed class Gost_R3410_2012_256_KeyExchange : Gost_R3410_KeyExchange 7 | { 8 | /// 9 | protected override OidValue KeyAlgorithm => Gost_R3410_2012_256_Constants.KeyAlgorithm; 10 | 11 | /// 12 | protected override Gost_R3410_PublicKeyParams CreatePublicKeyParams() => new Gost_R3410_2012_256_PublicKeyParams(); 13 | 14 | /// 15 | protected override Gost_R3410_KeyExchangeParams CreateKeyExchangeParams() => new Gost_R3410_2012_256_KeyExchangeParams(); 16 | } 17 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Asn1/Gost/Gost_R3410_2012_512/Gost_R3410_2012_512_KeyExchange.cs: -------------------------------------------------------------------------------- 1 | using GostCryptography.Asn1.Gost.Gost_R3410; 2 | 3 | namespace GostCryptography.Asn1.Gost.Gost_R3410_2012_512 4 | { 5 | /// 6 | public sealed class Gost_R3410_2012_512_KeyExchange : Gost_R3410_KeyExchange 7 | { 8 | /// 9 | protected override OidValue KeyAlgorithm => Gost_R3410_2012_512_Constants.KeyAlgorithm; 10 | 11 | /// 12 | protected override Gost_R3410_PublicKeyParams CreatePublicKeyParams() => new Gost_R3410_2012_512_PublicKeyParams(); 13 | 14 | /// 15 | protected override Gost_R3410_KeyExchangeParams CreateKeyExchangeParams() => new Gost_R3410_2012_512_KeyExchangeParams(); 16 | } 17 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Gost_R3410/Gost_R3410_2001_KeyExchangeXmlSerializer.cs: -------------------------------------------------------------------------------- 1 | using GostCryptography.Asn1.Gost.Gost_R3410_2001; 2 | 3 | namespace GostCryptography.Gost_R3410 4 | { 5 | /// 6 | /// XML-сериализатора параметров ключа цифровой подписи ГОСТ Р 34.10-2001. 7 | /// 8 | public sealed class Gost_R3410_2001_KeyExchangeXmlSerializer : Gost_R3410_KeyExchangeXmlSerializer 9 | { 10 | /// 11 | /// Имя тега с информацией о параметрах ключа ГОСТ Р 34.10-2001. 12 | /// 13 | public const string KeyValueTag = "GostKeyValue"; 14 | 15 | 16 | /// 17 | public Gost_R3410_2001_KeyExchangeXmlSerializer() : base(KeyValueTag) 18 | { 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Gost_R3410/Gost_R3410_2012_256_KeyExchangeXmlSerializer.cs: -------------------------------------------------------------------------------- 1 | using GostCryptography.Asn1.Gost.Gost_R3410_2012_256; 2 | 3 | namespace GostCryptography.Gost_R3410 4 | { 5 | /// 6 | /// XML-сериализатора параметров ключа цифровой подписи ГОСТ Р 34.10-2012/256. 7 | /// 8 | public sealed class Gost_R3410_2012_256_KeyExchangeXmlSerializer : Gost_R3410_KeyExchangeXmlSerializer 9 | { 10 | /// 11 | /// Имя тега с информацией о параметрах ключа ГОСТ Р 34.10-2012/256. 12 | /// 13 | public const string KeyValueTag = "Gost_R3410_2012_256_KeyValue"; 14 | 15 | 16 | /// 17 | public Gost_R3410_2012_256_KeyExchangeXmlSerializer() : base(KeyValueTag) 18 | { 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Gost_R3410/Gost_R3410_2012_512_KeyExchangeXmlSerializer.cs: -------------------------------------------------------------------------------- 1 | using GostCryptography.Asn1.Gost.Gost_R3410_2012_512; 2 | 3 | namespace GostCryptography.Gost_R3410 4 | { 5 | /// 6 | /// XML-сериализатора параметров ключа цифровой подписи ГОСТ Р 34.10-2012/512. 7 | /// 8 | public sealed class Gost_R3410_2012_512_KeyExchangeXmlSerializer : Gost_R3410_KeyExchangeXmlSerializer 9 | { 10 | /// 11 | /// Имя тега с информацией о параметрах ключа ГОСТ Р 34.10-2012/512. 12 | /// 13 | public const string KeyValueTag = "Gost_R3410_2012_512_KeyValue"; 14 | 15 | 16 | /// 17 | public Gost_R3410_2012_512_KeyExchangeXmlSerializer() : base(KeyValueTag) 18 | { 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Gost_R3410/Gost_R3410_2001_KeyExchangeAlgorithm.cs: -------------------------------------------------------------------------------- 1 | using System.Security; 2 | 3 | using GostCryptography.Asn1.Gost.Gost_R3410_2001; 4 | using GostCryptography.Base; 5 | using GostCryptography.Native; 6 | 7 | namespace GostCryptography.Gost_R3410 8 | { 9 | /// 10 | public sealed class Gost_R3410_2001_KeyExchangeAlgorithm : Gost_R3410_KeyExchangeAlgorithm 11 | { 12 | /// 13 | [SecurityCritical] 14 | public Gost_R3410_2001_KeyExchangeAlgorithm(ProviderType providerType, SafeProvHandleImpl provHandle, SafeKeyHandleImpl keyHandle, Gost_R3410_2001_KeyExchangeParams keyExchangeParameters, int keySize, int signatureAlgId) 15 | : base(providerType, provHandle, keyHandle, keyExchangeParameters, keySize, signatureAlgId) 16 | { 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Gost_R3410/Gost_R3410_2012_256_KeyExchangeAlgorithm.cs: -------------------------------------------------------------------------------- 1 | using System.Security; 2 | 3 | using GostCryptography.Asn1.Gost.Gost_R3410_2012_256; 4 | using GostCryptography.Base; 5 | using GostCryptography.Native; 6 | 7 | namespace GostCryptography.Gost_R3410 8 | { 9 | /// 10 | public sealed class Gost_R3410_2012_256_KeyExchangeAlgorithm : Gost_R3410_KeyExchangeAlgorithm 11 | { 12 | /// 13 | [SecurityCritical] 14 | public Gost_R3410_2012_256_KeyExchangeAlgorithm(ProviderType providerType, SafeProvHandleImpl provHandle, SafeKeyHandleImpl keyHandle, Gost_R3410_2012_256_KeyExchangeParams keyExchangeParameters, int keySize, int signatureAlgId) 15 | : base(providerType, provHandle, keyHandle, keyExchangeParameters, keySize, signatureAlgId) 16 | { 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Gost_R3410/Gost_R3410_2012_512_KeyExchangeAlgorithm.cs: -------------------------------------------------------------------------------- 1 | using System.Security; 2 | 3 | using GostCryptography.Asn1.Gost.Gost_R3410_2012_512; 4 | using GostCryptography.Base; 5 | using GostCryptography.Native; 6 | 7 | namespace GostCryptography.Gost_R3410 8 | { 9 | /// 10 | public sealed class Gost_R3410_2012_512_KeyExchangeAlgorithm : Gost_R3410_KeyExchangeAlgorithm 11 | { 12 | /// 13 | [SecurityCritical] 14 | public Gost_R3410_2012_512_KeyExchangeAlgorithm(ProviderType providerType, SafeProvHandleImpl provHandle, SafeKeyHandleImpl keyHandle, Gost_R3410_2012_512_KeyExchangeParams keyExchangeParameters, int keySize, int signatureAlgId) 15 | : base(providerType, provHandle, keyHandle, keyExchangeParameters, keySize, signatureAlgId) 16 | { 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Gost_R3410/Gost_R3410_2001_KeyExchangeDeformatter.cs: -------------------------------------------------------------------------------- 1 | using System.Security.Cryptography; 2 | 3 | using GostCryptography.Asn1.Gost.Gost_R3410_2001; 4 | 5 | namespace GostCryptography.Gost_R3410 6 | { 7 | /// 8 | /// Реализация дешифрования общего секретного ключа по ГОСТ Р 34.10-2001. 9 | /// 10 | public sealed class Gost_R3410_2001_KeyExchangeDeformatter : Gost_R3410_KeyExchangeDeformatter< 11 | Gost_R3410_2001_KeyExchange, 12 | Gost_R3410_2001_KeyExchangeParams, 13 | Gost_R3410_2001_KeyExchangeAlgorithm> 14 | { 15 | /// 16 | public Gost_R3410_2001_KeyExchangeDeformatter() 17 | { 18 | } 19 | 20 | /// 21 | public Gost_R3410_2001_KeyExchangeDeformatter(AsymmetricAlgorithm privateKey) : base(privateKey) 22 | { 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Gost_R3410/Gost_R3410_2001_SignatureDescription.cs: -------------------------------------------------------------------------------- 1 | using GostCryptography.Base; 2 | using GostCryptography.Gost_R3411; 3 | 4 | namespace GostCryptography.Gost_R3410 5 | { 6 | /// 7 | /// Информация о свойствах цифровой подписи ГОСТ Р 34.10-2001. 8 | /// 9 | public sealed class Gost_R3410_2001_SignatureDescription : GostSignatureDescription 10 | { 11 | /// 12 | public Gost_R3410_2001_SignatureDescription() 13 | { 14 | KeyAlgorithm = typeof(Gost_R3410_2001_AsymmetricAlgorithm).AssemblyQualifiedName; 15 | DigestAlgorithm = typeof(Gost_R3411_94_HashAlgorithm).AssemblyQualifiedName; 16 | FormatterAlgorithm = typeof(GostSignatureFormatter).AssemblyQualifiedName; 17 | DeformatterAlgorithm = typeof(GostSignatureDeformatter).AssemblyQualifiedName; 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Asn1/Ber/Asn1CharSet.cs: -------------------------------------------------------------------------------- 1 | namespace GostCryptography.Asn1.Ber 2 | { 3 | public abstract class Asn1CharSet 4 | { 5 | private readonly int _aBitsPerChar; 6 | private readonly int _uBitsPerChar; 7 | 8 | protected internal Asn1CharSet(int nchars) 9 | { 10 | _uBitsPerChar = Asn1Integer.GetBitCount(nchars - 1); 11 | _aBitsPerChar = 1; 12 | 13 | while (_uBitsPerChar > _aBitsPerChar) 14 | { 15 | _aBitsPerChar = _aBitsPerChar << 1; 16 | } 17 | } 18 | 19 | public abstract int MaxValue { get; } 20 | 21 | public abstract int GetCharAtIndex(int index); 22 | 23 | public abstract int GetCharIndex(int charValue); 24 | 25 | public virtual int GetNumBitsPerChar(bool aligned) 26 | { 27 | if (!aligned) 28 | { 29 | return _uBitsPerChar; 30 | } 31 | 32 | return _aBitsPerChar; 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Native/SafeHashHandleImpl.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Security; 3 | 4 | using Microsoft.Win32.SafeHandles; 5 | 6 | namespace GostCryptography.Native 7 | { 8 | /// 9 | /// Дескриптор функции хэширования криптографического провайдера. 10 | /// 11 | [SecurityCritical] 12 | public class SafeHashHandleImpl : SafeHandleZeroOrMinusOneIsInvalid 13 | { 14 | public static SafeHashHandleImpl InvalidHandle => new SafeHashHandleImpl(IntPtr.Zero); 15 | 16 | 17 | public SafeHashHandleImpl() : base(true) 18 | { 19 | } 20 | 21 | public SafeHashHandleImpl(IntPtr handle) : base(true) 22 | { 23 | SetHandle(handle); 24 | } 25 | 26 | 27 | [SecurityCritical] 28 | protected override bool ReleaseHandle() 29 | { 30 | CryptoApi.CryptDestroyHash(handle); 31 | return true; 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Gost_R3410/Gost_R3410_2012_256_KeyExchangeDeformatter.cs: -------------------------------------------------------------------------------- 1 | using System.Security.Cryptography; 2 | 3 | using GostCryptography.Asn1.Gost.Gost_R3410_2012_256; 4 | 5 | namespace GostCryptography.Gost_R3410 6 | { 7 | /// 8 | /// Реализация дешифрования общего секретного ключа по ГОСТ Р 34.10-2012/256. 9 | /// 10 | public sealed class Gost_R3410_2012_256_KeyExchangeDeformatter : Gost_R3410_KeyExchangeDeformatter< 11 | Gost_R3410_2012_256_KeyExchange, 12 | Gost_R3410_2012_256_KeyExchangeParams, 13 | Gost_R3410_2012_256_KeyExchangeAlgorithm> 14 | { 15 | /// 16 | public Gost_R3410_2012_256_KeyExchangeDeformatter() 17 | { 18 | } 19 | 20 | /// 21 | public Gost_R3410_2012_256_KeyExchangeDeformatter(AsymmetricAlgorithm privateKey) : base(privateKey) 22 | { 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Gost_R3410/Gost_R3410_2012_512_KeyExchangeDeformatter.cs: -------------------------------------------------------------------------------- 1 | using System.Security.Cryptography; 2 | 3 | using GostCryptography.Asn1.Gost.Gost_R3410_2012_512; 4 | 5 | namespace GostCryptography.Gost_R3410 6 | { 7 | /// 8 | /// Реализация дешифрования общего секретного ключа по ГОСТ Р 34.10-2012/512. 9 | /// 10 | public sealed class Gost_R3410_2012_512_KeyExchangeDeformatter : Gost_R3410_KeyExchangeDeformatter< 11 | Gost_R3410_2012_512_KeyExchange, 12 | Gost_R3410_2012_512_KeyExchangeParams, 13 | Gost_R3410_2012_512_KeyExchangeAlgorithm> 14 | { 15 | /// 16 | public Gost_R3410_2012_512_KeyExchangeDeformatter() 17 | { 18 | } 19 | 20 | /// 21 | public Gost_R3410_2012_512_KeyExchangeDeformatter(AsymmetricAlgorithm privateKey) : base(privateKey) 22 | { 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Gost_R3410/Gost_R3410_2012_256_SignatureDescription.cs: -------------------------------------------------------------------------------- 1 | using GostCryptography.Base; 2 | using GostCryptography.Gost_R3411; 3 | 4 | namespace GostCryptography.Gost_R3410 5 | { 6 | /// 7 | /// Информация о свойствах цифровой подписи ГОСТ Р 34.10-2012/256. 8 | /// 9 | public sealed class Gost_R3410_2012_256_SignatureDescription : GostSignatureDescription 10 | { 11 | /// 12 | public Gost_R3410_2012_256_SignatureDescription() 13 | { 14 | KeyAlgorithm = typeof(Gost_R3410_2012_256_AsymmetricAlgorithm).AssemblyQualifiedName; 15 | DigestAlgorithm = typeof(Gost_R3411_2012_256_HashAlgorithm).AssemblyQualifiedName; 16 | FormatterAlgorithm = typeof(GostSignatureFormatter).AssemblyQualifiedName; 17 | DeformatterAlgorithm = typeof(GostSignatureDeformatter).AssemblyQualifiedName; 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Gost_R3410/Gost_R3410_2012_512_SignatureDescription.cs: -------------------------------------------------------------------------------- 1 | using GostCryptography.Base; 2 | using GostCryptography.Gost_R3411; 3 | 4 | namespace GostCryptography.Gost_R3410 5 | { 6 | /// 7 | /// Информация о свойствах цифровой подписи ГОСТ Р 34.10-2012/512. 8 | /// 9 | public sealed class Gost_R3410_2012_512_SignatureDescription : GostSignatureDescription 10 | { 11 | /// 12 | public Gost_R3410_2012_512_SignatureDescription() 13 | { 14 | KeyAlgorithm = typeof(Gost_R3410_2012_512_AsymmetricAlgorithm).AssemblyQualifiedName; 15 | DigestAlgorithm = typeof(Gost_R3411_2012_512_HashAlgorithm).AssemblyQualifiedName; 16 | FormatterAlgorithm = typeof(GostSignatureFormatter).AssemblyQualifiedName; 17 | DeformatterAlgorithm = typeof(GostSignatureDeformatter).AssemblyQualifiedName; 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | push: 5 | branches: [ master ] 6 | pull_request: 7 | branches: [ master ] 8 | 9 | workflow_dispatch: 10 | 11 | jobs: 12 | build: 13 | runs-on: ubuntu-latest 14 | 15 | steps: 16 | - uses: actions/checkout@v2 17 | - name: Setup .NET 18 | uses: actions/setup-dotnet@v1 19 | with: 20 | dotnet-version: 6.0.x 21 | 22 | - name: Install dependencies 23 | run: dotnet restore GostCryptography.sln 24 | 25 | - name: Build 26 | run: dotnet build GostCryptography.sln --configuration Release --no-restore 27 | 28 | - name: Publish 29 | uses: brandedoutcast/publish-nuget@v2.5.2 30 | with: 31 | PROJECT_FILE_PATH: Source/GostCryptography/GostCryptography.csproj 32 | NUGET_KEY: ${{secrets.NUGET}} 33 | -------------------------------------------------------------------------------- /Source/GostCryptography/Gost_28147_89/Gost_28147_89_ImitHashAlgorithmBase.cs: -------------------------------------------------------------------------------- 1 | using GostCryptography.Base; 2 | 3 | namespace GostCryptography.Gost_28147_89 4 | { 5 | /// 6 | /// Базовый класс для всех реализаций функции вычисления имитовставки по ГОСТ 28147-89. 7 | /// 8 | public abstract class Gost_28147_89_ImitHashAlgorithmBase : GostKeyedHashAlgorithm 9 | { 10 | /// 11 | protected Gost_28147_89_ImitHashAlgorithmBase(int hashSize) : base(hashSize) 12 | { 13 | } 14 | 15 | /// 16 | protected Gost_28147_89_ImitHashAlgorithmBase(ProviderType providerType, int hashSize) : base(providerType, hashSize) 17 | { 18 | } 19 | 20 | 21 | /// 22 | /// Алгоритм симметричного шифрования ключа. 23 | /// 24 | public virtual Gost_28147_89_SymmetricAlgorithmBase KeyAlgorithm { get; set; } 25 | } 26 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Asn1/Ber/Asn1BerInputStream.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | 3 | namespace GostCryptography.Asn1.Ber 4 | { 5 | public class Asn1BerInputStream : Asn1BerDecodeBuffer, IAsn1InputStream 6 | { 7 | public Asn1BerInputStream(Stream inputStream) 8 | : base(inputStream) 9 | { 10 | } 11 | 12 | public virtual int Available() 13 | { 14 | var inputStream = GetInputStream(); 15 | 16 | if (inputStream != null) 17 | { 18 | var num = inputStream.Length - inputStream.Position; 19 | return (int)num; 20 | } 21 | 22 | return 0; 23 | } 24 | 25 | public virtual void Close() 26 | { 27 | var inputStream = GetInputStream(); 28 | 29 | if (inputStream != null) 30 | { 31 | inputStream.Close(); 32 | } 33 | } 34 | 35 | public virtual bool MarkSupported() 36 | { 37 | var inputStream = GetInputStream(); 38 | return ((inputStream != null) && inputStream.CanSeek); 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Asn1/Ber/Asn1DerInputStream.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | 3 | namespace GostCryptography.Asn1.Ber 4 | { 5 | public class Asn1DerInputStream : Asn1DerDecodeBuffer, IAsn1InputStream 6 | { 7 | public Asn1DerInputStream(Stream inputStream) 8 | : base(inputStream) 9 | { 10 | } 11 | 12 | public virtual int Available() 13 | { 14 | var inputStream = GetInputStream(); 15 | 16 | if (inputStream != null) 17 | { 18 | var num = inputStream.Length - inputStream.Position; 19 | return (int)num; 20 | } 21 | 22 | return 0; 23 | } 24 | 25 | public virtual void Close() 26 | { 27 | var inputStream = GetInputStream(); 28 | 29 | if (inputStream != null) 30 | { 31 | inputStream.Close(); 32 | } 33 | } 34 | 35 | public virtual bool MarkSupported() 36 | { 37 | var inputStream = GetInputStream(); 38 | 39 | return ((inputStream != null) && inputStream.CanSeek); 40 | } 41 | } 42 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Asn1/Gost/Gost_R3410_94/Gost_R3410_94_KeyExchangeParams.cs: -------------------------------------------------------------------------------- 1 | using GostCryptography.Asn1.Gost.Gost_R3410; 2 | 3 | namespace GostCryptography.Asn1.Gost.Gost_R3410_94 4 | { 5 | /// 6 | public sealed class Gost_R3410_94_KeyExchangeParams : Gost_R3410_KeyExchangeParams 7 | { 8 | /// 9 | public Gost_R3410_94_KeyExchangeParams() 10 | { 11 | } 12 | 13 | /// 14 | public Gost_R3410_94_KeyExchangeParams(Gost_R3410_94_KeyExchangeParams other) : base(other) 15 | { 16 | } 17 | 18 | 19 | /// 20 | public override Gost_R3410_KeyExchangeParams Clone() => new Gost_R3410_94_KeyExchangeParams(this); 21 | 22 | /// 23 | protected override Gost_R3410_PublicKey CreatePublicKey() => new Gost_R3410_94_PublicKey(); 24 | 25 | /// 26 | protected override Gost_R3410_PublicKeyParams CreatePublicKeyParams() => new Gost_R3410_94_PublicKeyParams(); 27 | } 28 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Asn1/Ber/Asn1Ia5String.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace GostCryptography.Asn1.Ber 4 | { 5 | [Serializable] 6 | public class Asn1Ia5String : Asn18BitCharString 7 | { 8 | public static readonly Asn1Tag Tag = new Asn1Tag(0, 0, Ia5StringTypeCode); 9 | 10 | public Asn1Ia5String() 11 | : base(Ia5StringTypeCode) 12 | { 13 | } 14 | 15 | public Asn1Ia5String(string data) 16 | : base(data, Ia5StringTypeCode) 17 | { 18 | } 19 | 20 | public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength) 21 | { 22 | Decode(buffer, explicitTagging, implicitLength, Tag); 23 | } 24 | 25 | public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging) 26 | { 27 | return Encode(buffer, explicitTagging, Tag); 28 | } 29 | 30 | public override void Encode(Asn1BerOutputStream outs, bool explicitTagging) 31 | { 32 | outs.EncodeCharString(Value, explicitTagging, Tag); 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Asn1/Ber/Asn1T61String.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace GostCryptography.Asn1.Ber 4 | { 5 | [Serializable] 6 | public class Asn1T61String : Asn1VarWidthCharString 7 | { 8 | public static readonly Asn1Tag Tag = new Asn1Tag(0, 0, T61StringTypeCode); 9 | 10 | public Asn1T61String() 11 | : base(T61StringTypeCode) 12 | { 13 | } 14 | 15 | public Asn1T61String(string data) 16 | : base(data, T61StringTypeCode) 17 | { 18 | } 19 | 20 | public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength) 21 | { 22 | Decode(buffer, explicitTagging, implicitLength, Tag); 23 | } 24 | 25 | public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging) 26 | { 27 | return Encode(buffer, explicitTagging, Tag); 28 | } 29 | 30 | public override void Encode(Asn1BerOutputStream outs, bool explicitTagging) 31 | { 32 | outs.EncodeCharString(Value, explicitTagging, Tag); 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Asn1/Gost/Gost_R3410_2001/Gost_R3410_2001_KeyExchangeParams.cs: -------------------------------------------------------------------------------- 1 | using GostCryptography.Asn1.Gost.Gost_R3410; 2 | 3 | namespace GostCryptography.Asn1.Gost.Gost_R3410_2001 4 | { 5 | /// 6 | public sealed class Gost_R3410_2001_KeyExchangeParams : Gost_R3410_KeyExchangeParams 7 | { 8 | /// 9 | public Gost_R3410_2001_KeyExchangeParams() 10 | { 11 | } 12 | 13 | /// 14 | public Gost_R3410_2001_KeyExchangeParams(Gost_R3410_2001_KeyExchangeParams other) : base(other) 15 | { 16 | } 17 | 18 | 19 | /// 20 | public override Gost_R3410_KeyExchangeParams Clone() => new Gost_R3410_2001_KeyExchangeParams(this); 21 | 22 | /// 23 | protected override Gost_R3410_PublicKey CreatePublicKey() => new Gost_R3410_2001_PublicKey(); 24 | 25 | /// 26 | protected override Gost_R3410_PublicKeyParams CreatePublicKeyParams() => new Gost_R3410_2001_PublicKeyParams(); 27 | } 28 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Asn1/Gost/Gost_R3410_94/Gost_R3410_94_Constants.cs: -------------------------------------------------------------------------------- 1 | namespace GostCryptography.Asn1.Gost.Gost_R3410_94 2 | { 3 | public static class Gost_R3410_94_Constants 4 | { 5 | /// 6 | /// Алгоритм ГОСТ Р 34.10-94, используемый при экспорте/импорте ключей. 7 | /// 8 | public static readonly OidValue KeyAlgorithm = OidValue.FromString("1.2.643.2.2.20"); 9 | 10 | /// 11 | /// Алгоритм Диффи-Хеллмана на базе потенциальной функции. 12 | /// 13 | public static readonly OidValue DhAlgorithm = OidValue.FromString("1.2.643.2.2.99"); 14 | 15 | /// 16 | /// Алгоритм цифровой подписи ГОСТ Р 34.10-94. 17 | /// 18 | public static readonly OidValue SignatureAlgorithm = OidValue.FromString("1.2.643.2.2.4"); 19 | 20 | /// 21 | /// Функция хэширования ГОСТ Р 34.11-94. 22 | /// 23 | public static readonly OidValue HashAlgorithm = OidValue.FromString("1.2.643.2.2.9"); 24 | } 25 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Asn1/Gost/Gost_R3410_2001/Gost_R3410_2001_Constants.cs: -------------------------------------------------------------------------------- 1 | namespace GostCryptography.Asn1.Gost.Gost_R3410_2001 2 | { 3 | public static class Gost_R3410_2001_Constants 4 | { 5 | /// 6 | /// Алгоритм ГОСТ Р 34.10-2001, используемый при экспорте/импорте ключей. 7 | /// 8 | public static readonly OidValue KeyAlgorithm = OidValue.FromString("1.2.643.2.2.19"); 9 | 10 | /// 11 | /// Алгоритм Диффи-Хеллмана на базе эллиптической кривой. 12 | /// 13 | public static readonly OidValue DhAlgorithm = OidValue.FromString("1.2.643.2.2.98"); 14 | 15 | /// 16 | /// Алгоритм цифровой подписи ГОСТ Р 34.10-2001. 17 | /// 18 | public static readonly OidValue SignatureAlgorithm = OidValue.FromString("1.2.643.2.2.3"); 19 | 20 | /// 21 | /// Функция хэширования ГОСТ Р 34.11-94. 22 | /// 23 | public static readonly OidValue HashAlgorithm = OidValue.FromString("1.2.643.2.2.9"); 24 | } 25 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Native/ISafeHandleProvider.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.InteropServices; 2 | using System.Security; 3 | 4 | namespace GostCryptography.Native 5 | { 6 | /// 7 | /// Провайдер дескрипторов криптографического объекта. 8 | /// 9 | /// Тип безопасного дескриптора. 10 | public interface ISafeHandleProvider where T : SafeHandle 11 | { 12 | /// 13 | /// Возвращает дескриптор объекта. 14 | /// 15 | T SafeHandle { [SecurityCritical] get; } 16 | } 17 | 18 | 19 | /// 20 | /// Методы расширения для . 21 | /// 22 | public static class SafeHandleProviderExtensions 23 | { 24 | /// 25 | /// Возвращает дескриптор объекта. 26 | /// 27 | [SecurityCritical] 28 | public static T GetSafeHandle(this ISafeHandleProvider provider) where T : SafeHandle 29 | { 30 | return provider.SafeHandle; 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Asn1/Ber/Asn1NumericString.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace GostCryptography.Asn1.Ber 4 | { 5 | [Serializable] 6 | public class Asn1NumericString : Asn18BitCharString 7 | { 8 | public static readonly Asn1Tag Tag = new Asn1Tag(0, 0, NumericStringTypeCode); 9 | 10 | public Asn1NumericString() 11 | : base(NumericStringTypeCode) 12 | { 13 | } 14 | 15 | public Asn1NumericString(string data) 16 | : base(data, NumericStringTypeCode) 17 | { 18 | } 19 | 20 | public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength) 21 | { 22 | Decode(buffer, explicitTagging, implicitLength, Tag); 23 | } 24 | 25 | public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging) 26 | { 27 | return Encode(buffer, explicitTagging, Tag); 28 | } 29 | 30 | public override void Encode(Asn1BerOutputStream outs, bool explicitTagging) 31 | { 32 | outs.EncodeCharString(Value, explicitTagging, Tag); 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Asn1/Ber/Asn1VisibleString.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace GostCryptography.Asn1.Ber 4 | { 5 | [Serializable] 6 | public class Asn1VisibleString : Asn18BitCharString 7 | { 8 | public static readonly Asn1Tag Tag = new Asn1Tag(0, 0, VisibleStringTypeCode); 9 | 10 | public Asn1VisibleString() 11 | : base(VisibleStringTypeCode) 12 | { 13 | } 14 | 15 | public Asn1VisibleString(string data) 16 | : base(data, VisibleStringTypeCode) 17 | { 18 | } 19 | 20 | public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength) 21 | { 22 | Decode(buffer, explicitTagging, implicitLength, Tag); 23 | } 24 | 25 | public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging) 26 | { 27 | return Encode(buffer, explicitTagging, Tag); 28 | } 29 | 30 | public override void Encode(Asn1BerOutputStream outs, bool explicitTagging) 31 | { 32 | outs.EncodeCharString(Value, explicitTagging, Tag); 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Asn1/Ber/Asn1GeneralString.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace GostCryptography.Asn1.Ber 4 | { 5 | [Serializable] 6 | public class Asn1GeneralString : Asn1VarWidthCharString 7 | { 8 | public static readonly Asn1Tag Tag = new Asn1Tag(0, 0, GeneralStringTypeCode); 9 | 10 | public Asn1GeneralString() 11 | : base(GeneralStringTypeCode) 12 | { 13 | } 14 | 15 | public Asn1GeneralString(string data) 16 | : base(data, GeneralStringTypeCode) 17 | { 18 | } 19 | 20 | public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength) 21 | { 22 | Decode(buffer, explicitTagging, implicitLength, Tag); 23 | } 24 | 25 | public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging) 26 | { 27 | return Encode(buffer, explicitTagging, Tag); 28 | } 29 | 30 | public override void Encode(Asn1BerOutputStream outs, bool explicitTagging) 31 | { 32 | outs.EncodeCharString(Value, explicitTagging, Tag); 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Asn1/Ber/Asn1GraphicString.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace GostCryptography.Asn1.Ber 4 | { 5 | [Serializable] 6 | public class Asn1GraphicString : Asn1VarWidthCharString 7 | { 8 | public static readonly Asn1Tag Tag = new Asn1Tag(0, 0, GraphicStringTypeCode); 9 | 10 | public Asn1GraphicString() 11 | : base(GraphicStringTypeCode) 12 | { 13 | } 14 | 15 | public Asn1GraphicString(string data) 16 | : base(data, GraphicStringTypeCode) 17 | { 18 | } 19 | 20 | public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength) 21 | { 22 | Decode(buffer, explicitTagging, implicitLength, Tag); 23 | } 24 | 25 | public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging) 26 | { 27 | return Encode(buffer, explicitTagging, Tag); 28 | } 29 | 30 | public override void Encode(Asn1BerOutputStream outs, bool explicitTagging) 31 | { 32 | outs.EncodeCharString(base.Value, explicitTagging, Tag); 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Asn1/Ber/Asn1VideotexString.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace GostCryptography.Asn1.Ber 4 | { 5 | [Serializable] 6 | public class Asn1VideotexString : Asn1VarWidthCharString 7 | { 8 | public static readonly Asn1Tag Tag = new Asn1Tag(0, 0, VideoTexStringTypeCode); 9 | 10 | public Asn1VideotexString() 11 | : base(VideoTexStringTypeCode) 12 | { 13 | } 14 | 15 | public Asn1VideotexString(string data) 16 | : base(data, VideoTexStringTypeCode) 17 | { 18 | } 19 | 20 | public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength) 21 | { 22 | Decode(buffer, explicitTagging, implicitLength, Tag); 23 | } 24 | 25 | public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging) 26 | { 27 | return Encode(buffer, explicitTagging, Tag); 28 | } 29 | 30 | public override void Encode(Asn1BerOutputStream outs, bool explicitTagging) 31 | { 32 | outs.EncodeCharString(Value, explicitTagging, Tag); 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Asn1/Ber/Asn1PrintableString.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace GostCryptography.Asn1.Ber 4 | { 5 | [Serializable] 6 | public class Asn1PrintableString : Asn18BitCharString 7 | { 8 | public static readonly Asn1Tag Tag = new Asn1Tag(0, 0, PrintableStringTypeCode); 9 | 10 | public Asn1PrintableString() 11 | : base(PrintableStringTypeCode) 12 | { 13 | } 14 | 15 | public Asn1PrintableString(string data) 16 | : base(data, PrintableStringTypeCode) 17 | { 18 | } 19 | 20 | public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength) 21 | { 22 | Decode(buffer, explicitTagging, implicitLength, Tag); 23 | } 24 | 25 | public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging) 26 | { 27 | return Encode(buffer, explicitTagging, Tag); 28 | } 29 | 30 | public override void Encode(Asn1BerOutputStream outs, bool explicitTagging) 31 | { 32 | outs.EncodeCharString(Value, explicitTagging, Tag); 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Asn1/Gost/Gost_R3410_2012_256/Gost_R3410_2012_256_KeyExchangeParams.cs: -------------------------------------------------------------------------------- 1 | using GostCryptography.Asn1.Gost.Gost_R3410; 2 | 3 | namespace GostCryptography.Asn1.Gost.Gost_R3410_2012_256 4 | { 5 | /// 6 | public sealed class Gost_R3410_2012_256_KeyExchangeParams : Gost_R3410_KeyExchangeParams 7 | { 8 | /// 9 | public Gost_R3410_2012_256_KeyExchangeParams() 10 | { 11 | } 12 | 13 | /// 14 | public Gost_R3410_2012_256_KeyExchangeParams(Gost_R3410_2012_256_KeyExchangeParams other) : base(other) 15 | { 16 | } 17 | 18 | 19 | /// 20 | public override Gost_R3410_KeyExchangeParams Clone() => new Gost_R3410_2012_256_KeyExchangeParams(this); 21 | 22 | /// 23 | protected override Gost_R3410_PublicKey CreatePublicKey() => new Gost_R3410_2012_256_PublicKey(); 24 | 25 | /// 26 | protected override Gost_R3410_PublicKeyParams CreatePublicKeyParams() => new Gost_R3410_2012_256_PublicKeyParams(); 27 | } 28 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Asn1/Gost/Gost_R3410_2012_512/Gost_R3410_2012_512_KeyExchangeParams.cs: -------------------------------------------------------------------------------- 1 | using GostCryptography.Asn1.Gost.Gost_R3410; 2 | 3 | namespace GostCryptography.Asn1.Gost.Gost_R3410_2012_512 4 | { 5 | /// 6 | public sealed class Gost_R3410_2012_512_KeyExchangeParams : Gost_R3410_KeyExchangeParams 7 | { 8 | /// 9 | public Gost_R3410_2012_512_KeyExchangeParams() 10 | { 11 | } 12 | 13 | /// 14 | public Gost_R3410_2012_512_KeyExchangeParams(Gost_R3410_2012_512_KeyExchangeParams other) : base(other) 15 | { 16 | } 17 | 18 | 19 | /// 20 | public override Gost_R3410_KeyExchangeParams Clone() => new Gost_R3410_2012_512_KeyExchangeParams(this); 21 | 22 | /// 23 | protected override Gost_R3410_PublicKey CreatePublicKey() => new Gost_R3410_2012_512_PublicKey(); 24 | 25 | /// 26 | protected override Gost_R3410_PublicKeyParams CreatePublicKeyParams() => new Gost_R3410_2012_512_PublicKeyParams(); 27 | } 28 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Asn1/Ber/Asn1ObjectDescriptor.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace GostCryptography.Asn1.Ber 4 | { 5 | [Serializable] 6 | public class Asn1ObjectDescriptor : Asn1VarWidthCharString 7 | { 8 | public static readonly Asn1Tag Tag = new Asn1Tag(0, 0, ObjectDescriptorTypeCode); 9 | 10 | public Asn1ObjectDescriptor() 11 | : base(ObjectDescriptorTypeCode) 12 | { 13 | } 14 | 15 | public Asn1ObjectDescriptor(string data) 16 | : base(data, ObjectDescriptorTypeCode) 17 | { 18 | } 19 | 20 | public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength) 21 | { 22 | Decode(buffer, explicitTagging, implicitLength, Tag); 23 | } 24 | 25 | public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging) 26 | { 27 | return Encode(buffer, explicitTagging, Tag); 28 | } 29 | 30 | public override void Encode(Asn1BerOutputStream outs, bool explicitTagging) 31 | { 32 | outs.EncodeCharString(Value, explicitTagging, Tag); 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Native/SafeKeyHandleImpl.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Security; 3 | 4 | using Microsoft.Win32.SafeHandles; 5 | 6 | namespace GostCryptography.Native 7 | { 8 | /// 9 | /// Дескриптор ключа криптографического провайдера. 10 | /// 11 | [SecurityCritical] 12 | public sealed class SafeKeyHandleImpl : SafeHandleZeroOrMinusOneIsInvalid 13 | { 14 | public SafeKeyHandleImpl() 15 | : base(true) 16 | { 17 | } 18 | 19 | public SafeKeyHandleImpl(IntPtr handle) 20 | : base(true) 21 | { 22 | SetHandle(handle); 23 | } 24 | 25 | public static SafeKeyHandleImpl InvalidHandle 26 | { 27 | get { return new SafeKeyHandleImpl(IntPtr.Zero); } 28 | } 29 | 30 | [SecurityCritical] 31 | protected override bool ReleaseHandle() 32 | { 33 | CryptoApi.CryptDestroyKey(handle); 34 | return true; 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Asn1/Gost/Gost_28147_89/Gost_28147_89_Iv.cs: -------------------------------------------------------------------------------- 1 | using GostCryptography.Asn1.Ber; 2 | using GostCryptography.Properties; 3 | 4 | namespace GostCryptography.Asn1.Gost.Gost_28147_89 5 | { 6 | public sealed class Gost_28147_89_Iv : Asn1OctetString 7 | { 8 | public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength) 9 | { 10 | base.Decode(buffer, explicitTagging, implicitLength); 11 | 12 | if (Length != 8) 13 | { 14 | throw ExceptionUtility.CryptographicException(Resources.Asn1ConsVioException, nameof(Length), Length); 15 | } 16 | } 17 | 18 | public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging) 19 | { 20 | if (Length != 8) 21 | { 22 | throw ExceptionUtility.CryptographicException(Resources.Asn1ConsVioException, nameof(Length), Length); 23 | } 24 | 25 | var len = base.Encode(buffer, false); 26 | 27 | if (explicitTagging) 28 | { 29 | len += buffer.EncodeTagAndLength(Tag, len); 30 | } 31 | 32 | return len; 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Asn1/Ber/Asn1CharRange.cs: -------------------------------------------------------------------------------- 1 | using GostCryptography.Properties; 2 | 3 | namespace GostCryptography.Asn1.Ber 4 | { 5 | public class Asn1CharRange : Asn1CharSet 6 | { 7 | private readonly int _lower; 8 | private readonly int _upper; 9 | 10 | public Asn1CharRange(int lower, int upper) 11 | : base((upper - lower) + 1) 12 | { 13 | _lower = lower; 14 | _upper = upper; 15 | } 16 | 17 | public override int MaxValue 18 | { 19 | get { return _upper; } 20 | } 21 | 22 | public override int GetCharAtIndex(int index) 23 | { 24 | index += _lower; 25 | 26 | if (index > _upper) 27 | { 28 | throw ExceptionUtility.CryptographicException(Resources.Asn1ConsVioException, "Character index", index); 29 | } 30 | 31 | return index; 32 | } 33 | 34 | public override int GetCharIndex(int charValue) 35 | { 36 | var num = charValue - _lower; 37 | 38 | if (num < 0) 39 | { 40 | throw ExceptionUtility.CryptographicException(Resources.Asn1ConsVioException, "Character index", charValue); 41 | } 42 | 43 | return num; 44 | } 45 | } 46 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Asn1/Gost/Gost_R3410_2012_256/Gost_R3410_2012_256_Constants.cs: -------------------------------------------------------------------------------- 1 | namespace GostCryptography.Asn1.Gost.Gost_R3410_2012_256 2 | { 3 | public static class Gost_R3410_2012_256_Constants 4 | { 5 | /// 6 | /// Алгоритм ГОСТ Р 34.10-2012 для ключей длины 256 бит, используемый при экспорте/импорте ключей. 7 | /// 8 | public static readonly OidValue KeyAlgorithm = OidValue.FromString("1.2.643.7.1.1.1.1"); 9 | 10 | /// 11 | /// Алгоритм Диффи-Хеллмана на базе эллиптической кривой для ключей длины 256 бит. 12 | /// 13 | public static readonly OidValue DhAlgorithm = OidValue.FromString("1.2.643.7.1.1.6.1"); 14 | 15 | /// 16 | /// Алгоритм цифровой подписи ГОСТ Р 34.10-2012 для ключей длины 256 бит. 17 | /// 18 | public static readonly OidValue SignatureAlgorithm = OidValue.FromString("1.2.643.7.1.1.3.2"); 19 | 20 | /// 21 | /// Функция хэширования ГОСТ Р 34.11-2012, длина выхода 256 бит. 22 | /// 23 | public static readonly OidValue HashAlgorithm = OidValue.FromString("1.2.643.7.1.1.2.2"); 24 | } 25 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Asn1/Gost/Gost_R3410_2012_512/Gost_R3410_2012_512_Constants.cs: -------------------------------------------------------------------------------- 1 | namespace GostCryptography.Asn1.Gost.Gost_R3410_2012_512 2 | { 3 | public static class Gost_R3410_2012_512_Constants 4 | { 5 | /// 6 | /// Алгоритм ГОСТ Р 34.10-2012 для ключей длины 512 бит, используемый при экспорте/импорте ключей. 7 | /// 8 | public static readonly OidValue KeyAlgorithm = OidValue.FromString("1.2.643.7.1.1.1.2"); 9 | 10 | /// 11 | /// Алгоритм Диффи-Хеллмана на базе эллиптической кривой для ключей длины 512 бит. 12 | /// 13 | public static readonly OidValue DhAlgorithm = OidValue.FromString("1.2.643.7.1.1.6.2"); 14 | 15 | /// 16 | /// Алгоритм цифровой подписи ГОСТ Р 34.10-2012 для ключей длины 512 бит. 17 | /// 18 | public static readonly OidValue SignatureAlgorithm = OidValue.FromString("1.2.643.7.1.1.3.3"); 19 | 20 | /// 21 | /// Функция хэширования ГОСТ Р 34.11-2012, длина выхода 512 бит. 22 | /// 23 | public static readonly OidValue HashAlgorithm = OidValue.FromString("1.2.643.7.1.1.2.3"); 24 | } 25 | } -------------------------------------------------------------------------------- /Source/GostCryptography.Tests/GostCryptography.Tests.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net6.0 5 | false 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | True 21 | True 22 | Resources.resx 23 | 24 | 25 | 26 | 27 | 28 | ResXFileCodeGenerator 29 | Resources.Designer.cs 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /Source/GostCryptography/Asn1/Ber/Asn1Choice.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace GostCryptography.Asn1.Ber 4 | { 5 | [Serializable] 6 | public abstract class Asn1Choice : Asn1Type 7 | { 8 | [NonSerialized] 9 | private int _choiceId; 10 | 11 | [NonSerialized] 12 | protected Asn1Type Element; 13 | 14 | 15 | public virtual int ChoiceId => _choiceId; 16 | 17 | public abstract string ElemName { get; } 18 | 19 | 20 | public virtual Asn1Type GetElement() 21 | { 22 | return Element; 23 | } 24 | 25 | public virtual void SetElement(int choiceId, Asn1Type element) 26 | { 27 | _choiceId = choiceId; 28 | 29 | Element = element; 30 | } 31 | 32 | 33 | public override bool Equals(object value) 34 | { 35 | var choice = value as Asn1Choice; 36 | 37 | if (choice == null) 38 | { 39 | return false; 40 | } 41 | 42 | if (_choiceId != choice._choiceId) 43 | { 44 | return false; 45 | } 46 | 47 | return Element.Equals(choice.Element); 48 | } 49 | 50 | public override int GetHashCode() 51 | { 52 | return Element?.GetHashCode() ?? base.GetHashCode(); 53 | } 54 | } 55 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Asn1/Ber/Asn1Null.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace GostCryptography.Asn1.Ber 4 | { 5 | [Serializable] 6 | public class Asn1Null : Asn1Type 7 | { 8 | public static readonly Asn1Tag Tag = new Asn1Tag(0, 0, NullTypeCode); 9 | public static readonly Asn1Null NullValue = new Asn1Null(); 10 | 11 | public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength) 12 | { 13 | if (explicitTagging) 14 | { 15 | MatchTag(buffer, Tag); 16 | } 17 | 18 | buffer.TypeCode = NullTypeCode; 19 | } 20 | 21 | public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging) 22 | { 23 | var len = 0; 24 | 25 | if (explicitTagging) 26 | { 27 | len += buffer.EncodeTagAndLength(Tag, len); 28 | } 29 | 30 | return len; 31 | } 32 | 33 | public override void Encode(Asn1BerOutputStream outs, bool explicitTagging) 34 | { 35 | if (explicitTagging) 36 | { 37 | outs.EncodeTag(Tag); 38 | } 39 | 40 | outs.EncodeLength(0); 41 | } 42 | 43 | public override string ToString() 44 | { 45 | return "NULL"; 46 | } 47 | } 48 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Alexander Mezhov 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /Source/GostCryptography/Asn1/Ber/Asn1TraceHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | 4 | namespace GostCryptography.Asn1.Ber 5 | { 6 | public class Asn1TraceHandler : IAsn1NamedEventHandler 7 | { 8 | internal StreamWriter mPrintStream; 9 | 10 | public Asn1TraceHandler() 11 | { 12 | mPrintStream = new StreamWriter(Console.OpenStandardOutput(), Console.Out.Encoding); 13 | mPrintStream.AutoFlush = true; 14 | } 15 | 16 | public Asn1TraceHandler(StreamWriter ps) 17 | { 18 | mPrintStream = ps; 19 | } 20 | 21 | public virtual void Characters(string svalue, short typeCode) 22 | { 23 | mPrintStream.WriteLine("data: " + svalue); 24 | } 25 | 26 | public virtual void EndElement(string name, int index) 27 | { 28 | mPrintStream.Write(name); 29 | if (index >= 0) 30 | { 31 | mPrintStream.Write("[" + index + "]"); 32 | } 33 | mPrintStream.WriteLine(": end"); 34 | } 35 | 36 | public virtual void StartElement(string name, int index) 37 | { 38 | mPrintStream.Write(name); 39 | if (index >= 0) 40 | { 41 | mPrintStream.Write("[" + index + "]"); 42 | } 43 | mPrintStream.WriteLine(": start"); 44 | } 45 | } 46 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Asn1/Gost/Gost_28147_89/Gost_28147_89_Key.cs: -------------------------------------------------------------------------------- 1 | using GostCryptography.Asn1.Ber; 2 | using GostCryptography.Properties; 3 | 4 | namespace GostCryptography.Asn1.Gost.Gost_28147_89 5 | { 6 | public sealed class Gost_28147_89_Key : Asn1OctetString 7 | { 8 | public Gost_28147_89_Key() 9 | { 10 | } 11 | 12 | public Gost_28147_89_Key(byte[] data) 13 | : base(data) 14 | { 15 | } 16 | 17 | public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength) 18 | { 19 | base.Decode(buffer, explicitTagging, implicitLength); 20 | 21 | if (Length != 32) 22 | { 23 | throw ExceptionUtility.CryptographicException(Resources.Asn1ConsVioException, nameof(Length), Length); 24 | } 25 | } 26 | 27 | public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging) 28 | { 29 | if (Length != 32) 30 | { 31 | throw ExceptionUtility.CryptographicException(Resources.Asn1ConsVioException, nameof(Length), Length); 32 | } 33 | 34 | var len = base.Encode(buffer, false); 35 | 36 | if (explicitTagging) 37 | { 38 | len += buffer.EncodeTagAndLength(Tag, len); 39 | } 40 | 41 | return len; 42 | } 43 | } 44 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Base/GostPrf.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Security; 3 | 4 | namespace GostCryptography.Base 5 | { 6 | /// 7 | /// Базовый класс для всех алгоритмов генерации псевдослучайной последовательности (Pseudorandom Function, PRF) ГОСТ. 8 | /// 9 | public abstract class GostPRF : IDisposable, IGostAlgorithm 10 | { 11 | /// 12 | /// Конструктор. 13 | /// 14 | /// Тип криптографического провайдера. 15 | [SecuritySafeCritical] 16 | protected GostPRF(ProviderType providerType) 17 | { 18 | ProviderType = providerType; 19 | } 20 | 21 | 22 | /// 23 | public ProviderType ProviderType { get; } 24 | 25 | /// 26 | public abstract string AlgorithmName { get; } 27 | 28 | 29 | /// 30 | /// Освобождает неуправляемые ресурсы. 31 | /// 32 | protected virtual void Dispose(bool disposing) 33 | { 34 | } 35 | 36 | /// 37 | public void Dispose() 38 | { 39 | Dispose(true); 40 | GC.SuppressFinalize(this); 41 | } 42 | 43 | /// 44 | ~GostPRF() 45 | { 46 | Dispose(false); 47 | } 48 | } 49 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Asn1/Gost/Gost_R3410/Gost_R3410_PublicKey.cs: -------------------------------------------------------------------------------- 1 | using GostCryptography.Asn1.Ber; 2 | using GostCryptography.Properties; 3 | 4 | namespace GostCryptography.Asn1.Gost.Gost_R3410 5 | { 6 | public abstract class Gost_R3410_PublicKey : Asn1OctetString 7 | { 8 | private readonly int _keySize; 9 | 10 | protected Gost_R3410_PublicKey(int keySize) 11 | { 12 | _keySize = keySize; 13 | } 14 | 15 | public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength) 16 | { 17 | base.Decode(buffer, explicitTagging, implicitLength); 18 | 19 | if (Length != _keySize) 20 | { 21 | throw ExceptionUtility.CryptographicException(Resources.Asn1ConsVioException, nameof(Length), Length); 22 | } 23 | } 24 | 25 | public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging) 26 | { 27 | if (Length != _keySize) 28 | { 29 | throw ExceptionUtility.CryptographicException(Resources.Asn1ConsVioException, nameof(Length), Length); 30 | } 31 | 32 | var len = base.Encode(buffer, false); 33 | 34 | if (explicitTagging) 35 | { 36 | len += buffer.EncodeTagAndLength(Tag, len); 37 | } 38 | 39 | return len; 40 | } 41 | } 42 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Gost_R3410/Gost_R3410_2001_KeyExchangeFormatter.cs: -------------------------------------------------------------------------------- 1 | using System.Security.Cryptography; 2 | 3 | using GostCryptography.Asn1.Gost.Gost_R3410_2001; 4 | using GostCryptography.Base; 5 | 6 | namespace GostCryptography.Gost_R3410 7 | { 8 | /// 9 | /// Реализация шифрования общего секретного ключа по ГОСТ Р 34.10-2001. 10 | /// 11 | public sealed class Gost_R3410_2001_KeyExchangeFormatter : Gost_R3410_KeyExchangeFormatter< 12 | Gost_R3410_2001_KeyExchange, 13 | Gost_R3410_2001_KeyExchangeParams, 14 | Gost_R3410_2001_KeyExchangeAlgorithm> 15 | { 16 | /// 17 | public Gost_R3410_2001_KeyExchangeFormatter() 18 | { 19 | } 20 | 21 | /// 22 | public Gost_R3410_2001_KeyExchangeFormatter(AsymmetricAlgorithm publicKey) : base(publicKey) 23 | { 24 | } 25 | 26 | /// 27 | protected override Gost_R3410_EphemeralAsymmetricAlgorithm CreateEphemeralAlgorithm(ProviderType providerType, Gost_R3410_2001_KeyExchangeParams keyExchangeParameters) 28 | { 29 | return new Gost_R3410_2001_EphemeralAsymmetricAlgorithm(providerType, keyExchangeParameters); 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Base/GostSymmetricAlgorithm.cs: -------------------------------------------------------------------------------- 1 | using System.Security; 2 | using System.Security.Cryptography; 3 | 4 | using GostCryptography.Config; 5 | 6 | namespace GostCryptography.Base 7 | { 8 | /// 9 | /// Базовый класс для всех алгоритмов симметричного шифрования ГОСТ. 10 | /// 11 | public abstract class GostSymmetricAlgorithm : SymmetricAlgorithm, IGostAlgorithm 12 | { 13 | /// 14 | /// Конструктор. 15 | /// 16 | /// 17 | /// По умолчанию использует криптографический провайдер, установленный в . 18 | /// 19 | [SecuritySafeCritical] 20 | protected GostSymmetricAlgorithm() : this(GostCryptoConfig.ProviderType) 21 | { 22 | } 23 | 24 | /// 25 | /// Конструктор. 26 | /// 27 | /// Тип криптографического провайдера. 28 | [SecuritySafeCritical] 29 | protected GostSymmetricAlgorithm(ProviderType providerType) 30 | { 31 | ProviderType = providerType; 32 | } 33 | 34 | 35 | /// 36 | public ProviderType ProviderType { get; } 37 | 38 | /// 39 | public abstract string AlgorithmName { get; } 40 | } 41 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Asn1/Gost/Gost_28147_89/Gost_28147_89_Mac.cs: -------------------------------------------------------------------------------- 1 | using GostCryptography.Asn1.Ber; 2 | using GostCryptography.Properties; 3 | 4 | namespace GostCryptography.Asn1.Gost.Gost_28147_89 5 | { 6 | public sealed class Gost_28147_89_Mac : Asn1OctetString 7 | { 8 | public Gost_28147_89_Mac() 9 | { 10 | } 11 | 12 | public Gost_28147_89_Mac(byte[] data) 13 | : base(data) 14 | { 15 | } 16 | 17 | 18 | public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength) 19 | { 20 | base.Decode(buffer, explicitTagging, implicitLength); 21 | 22 | if ((Length < 1) || (Length > 4)) 23 | { 24 | throw ExceptionUtility.CryptographicException(Resources.Asn1ConsVioException, nameof(Length), Length); 25 | } 26 | } 27 | 28 | public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging) 29 | { 30 | if ((Length < 1) || (Length > 4)) 31 | { 32 | throw ExceptionUtility.CryptographicException(Resources.Asn1ConsVioException, nameof(Length), Length); 33 | } 34 | 35 | var len = base.Encode(buffer, false); 36 | 37 | if (explicitTagging) 38 | { 39 | len += buffer.EncodeTagAndLength(Tag, len); 40 | } 41 | 42 | return len; 43 | } 44 | } 45 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Gost_R3410/Gost_R3410_2012_256_KeyExchangeFormatter.cs: -------------------------------------------------------------------------------- 1 | using System.Security.Cryptography; 2 | 3 | using GostCryptography.Asn1.Gost.Gost_R3410_2012_256; 4 | using GostCryptography.Base; 5 | 6 | namespace GostCryptography.Gost_R3410 7 | { 8 | /// 9 | /// Реализация шифрования общего секретного ключа по ГОСТ Р 34.10-2012/256. 10 | /// 11 | public sealed class Gost_R3410_2012_256_KeyExchangeFormatter : Gost_R3410_KeyExchangeFormatter< 12 | Gost_R3410_2012_256_KeyExchange, 13 | Gost_R3410_2012_256_KeyExchangeParams, 14 | Gost_R3410_2012_256_KeyExchangeAlgorithm> 15 | { 16 | /// 17 | public Gost_R3410_2012_256_KeyExchangeFormatter() 18 | { 19 | } 20 | 21 | /// 22 | public Gost_R3410_2012_256_KeyExchangeFormatter(AsymmetricAlgorithm publicKey) : base(publicKey) 23 | { 24 | } 25 | 26 | /// 27 | protected override Gost_R3410_EphemeralAsymmetricAlgorithm CreateEphemeralAlgorithm(ProviderType providerType, Gost_R3410_2012_256_KeyExchangeParams keyExchangeParameters) 28 | { 29 | return new Gost_R3410_2012_256_EphemeralAsymmetricAlgorithm(providerType, keyExchangeParameters); 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Gost_R3410/Gost_R3410_2012_512_KeyExchangeFormatter.cs: -------------------------------------------------------------------------------- 1 | using System.Security.Cryptography; 2 | 3 | using GostCryptography.Asn1.Gost.Gost_R3410_2012_512; 4 | using GostCryptography.Base; 5 | 6 | namespace GostCryptography.Gost_R3410 7 | { 8 | /// 9 | /// Реализация шифрования общего секретного ключа по ГОСТ Р 34.10-2012/512. 10 | /// 11 | public sealed class Gost_R3410_2012_512_KeyExchangeFormatter : Gost_R3410_KeyExchangeFormatter< 12 | Gost_R3410_2012_512_KeyExchange, 13 | Gost_R3410_2012_512_KeyExchangeParams, 14 | Gost_R3410_2012_512_KeyExchangeAlgorithm> 15 | { 16 | /// 17 | public Gost_R3410_2012_512_KeyExchangeFormatter() 18 | { 19 | } 20 | 21 | /// 22 | public Gost_R3410_2012_512_KeyExchangeFormatter(AsymmetricAlgorithm publicKey) : base(publicKey) 23 | { 24 | } 25 | 26 | /// 27 | protected override Gost_R3410_EphemeralAsymmetricAlgorithm CreateEphemeralAlgorithm(ProviderType providerType, Gost_R3410_2012_512_KeyExchangeParams keyExchangeParameters) 28 | { 29 | return new Gost_R3410_2012_512_EphemeralAsymmetricAlgorithm(providerType, keyExchangeParameters); 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Xml/Gost_R3410_2001_KeyValue.cs: -------------------------------------------------------------------------------- 1 | using System.Security.Cryptography.Xml; 2 | 3 | using GostCryptography.Gost_R3410; 4 | 5 | namespace GostCryptography.Xml 6 | { 7 | /// 8 | /// Параметры открытого ключа цифровой подписи ГОСТ Р 34.10-2001 элемента . 9 | /// 10 | public sealed class Gost_R3410_2001_KeyValue : GostKeyValue 11 | { 12 | /// 13 | /// URI параметров ключа ГОСТ Р 34.10-2001. 14 | /// 15 | public const string KeyValueUrl = SignedXml.XmlDsigNamespaceUrl + " KeyValue/" + Gost_R3410_2001_KeyExchangeXmlSerializer.KeyValueTag; 16 | 17 | /// 18 | /// Известные URIs параметров ключа ГОСТ Р 34.10-2001. 19 | /// 20 | public static readonly string[] KnownValueUrls = { KeyValueUrl }; 21 | 22 | 23 | /// 24 | /// Создает экземпляр класса с новым ключом ГОСТ Р 34.10-2001. 25 | /// 26 | public Gost_R3410_2001_KeyValue() : base(new Gost_R3410_2001_AsymmetricAlgorithm()) 27 | { 28 | } 29 | 30 | /// 31 | /// Создает экземпляр класса с заданным ключом ГОСТ Р 34.10-2001. 32 | /// 33 | public Gost_R3410_2001_KeyValue(Gost_R3410_2001_AsymmetricAlgorithm publicKey) : base(publicKey) 34 | { 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Native/SafeStore.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Win32.SafeHandles; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Runtime.InteropServices; 5 | using System.Security; 6 | using System.Text; 7 | 8 | namespace GostCryptography.Native 9 | { 10 | [SecurityCritical] 11 | class SafeStore : SafeHandleZeroOrMinusOneIsInvalid 12 | { 13 | public static SafeStore InvalidHandle => new SafeStore(IntPtr.Zero); 14 | 15 | 16 | public SafeStore() : base(true) 17 | { 18 | } 19 | 20 | public SafeStore(IntPtr handle) : base(true) 21 | { 22 | SetHandle(handle); 23 | } 24 | 25 | 26 | [SecurityCritical] 27 | protected override bool ReleaseHandle() 28 | { 29 | 30 | 31 | return true; 32 | } 33 | 34 | protected override void Dispose(bool disposing) 35 | { 36 | if (handle != IntPtr.Zero) 37 | { 38 | if (!CryptoApi.CertCloseStore(this, 0)) 39 | { 40 | var errCode = Marshal.GetLastWin32Error(); 41 | throw new SystemException(errCode.ToString("x")); 42 | } 43 | } 44 | base.Dispose(disposing); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /Source/GostCryptography/Xml/Gost_R3410_2012_256_KeyValue.cs: -------------------------------------------------------------------------------- 1 | using System.Security.Cryptography.Xml; 2 | 3 | using GostCryptography.Gost_R3410; 4 | 5 | namespace GostCryptography.Xml 6 | { 7 | /// 8 | /// Параметры открытого ключа цифровой подписи ГОСТ Р 34.10-2012/256 элемента . 9 | /// 10 | public sealed class Gost_R3410_2012_256_KeyValue : GostKeyValue 11 | { 12 | /// 13 | /// URI параметров ключа ГОСТ Р 34.10-2012/256. 14 | /// 15 | public const string KeyValueUrl = SignedXml.XmlDsigNamespaceUrl + " KeyValue/" + Gost_R3410_2012_256_KeyExchangeXmlSerializer.KeyValueTag; 16 | 17 | /// 18 | /// Известные URIs параметров ключа ГОСТ Р 34.10-2012/256. 19 | /// 20 | public static readonly string[] KnownValueUrls = { KeyValueUrl }; 21 | 22 | 23 | /// 24 | /// Создает экземпляр класса с новым ключом ГОСТ Р 34.10-2012/256. 25 | /// 26 | public Gost_R3410_2012_256_KeyValue() : base(new Gost_R3410_2012_256_AsymmetricAlgorithm()) 27 | { 28 | } 29 | 30 | /// 31 | /// Создает экземпляр класса с заданным ключом ГОСТ Р 34.10-2012/256. 32 | /// 33 | public Gost_R3410_2012_256_KeyValue(Gost_R3410_2012_256_AsymmetricAlgorithm publicKey) : base(publicKey) 34 | { 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Xml/Gost_R3410_2012_512_KeyValue.cs: -------------------------------------------------------------------------------- 1 | using System.Security.Cryptography.Xml; 2 | 3 | using GostCryptography.Gost_R3410; 4 | 5 | namespace GostCryptography.Xml 6 | { 7 | /// 8 | /// Параметры открытого ключа цифровой подписи ГОСТ Р 34.10-2012/512 элемента . 9 | /// 10 | public sealed class Gost_R3410_2012_512_KeyValue : GostKeyValue 11 | { 12 | /// 13 | /// URI параметров ключа ГОСТ Р 34.10-2012/512. 14 | /// 15 | public const string KeyValueUrl = SignedXml.XmlDsigNamespaceUrl + " KeyValue/" + Gost_R3410_2012_512_KeyExchangeXmlSerializer.KeyValueTag; 16 | 17 | /// 18 | /// Известные URIs параметров ключа ГОСТ Р 34.10-2012/512. 19 | /// 20 | public static readonly string[] KnownValueUrls = { KeyValueUrl }; 21 | 22 | 23 | /// 24 | /// Создает экземпляр класса с новым ключом ГОСТ Р 34.10-2012/512. 25 | /// 26 | public Gost_R3410_2012_512_KeyValue() : base(new Gost_R3410_2012_512_AsymmetricAlgorithm()) 27 | { 28 | } 29 | 30 | /// 31 | /// Создает экземпляр класса с заданным ключом ГОСТ Р 34.10-2012/512. 32 | /// 33 | public Gost_R3410_2012_512_KeyValue(Gost_R3410_2012_512_AsymmetricAlgorithm publicKey) : base(publicKey) 34 | { 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /Source/GostCryptography.Tests/Gost_R3411/Gost_R3411_94_HashAlgorithmTest.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | using System.Text; 3 | 4 | using GostCryptography.Base; 5 | using GostCryptography.Gost_R3411; 6 | 7 | using NUnit.Framework; 8 | 9 | namespace GostCryptography.Tests.Gost_R3411 10 | { 11 | /// 12 | /// Вычисление хэша в соответствии с ГОСТ Р 34.11-94. 13 | /// 14 | /// 15 | /// Тест создает поток байт, вычисляет хэш в соответствии с ГОСТ Р 34.11-94 и проверяет его корректность. 16 | /// 17 | [TestFixture(Description = "Вычисление хэша в соответствии с ГОСТ Р 34.11-94")] 18 | public class Gost_R3411_94_HashAlgorithmTest 19 | { 20 | [Test] 21 | [TestCaseSource(typeof(TestConfig), nameof(TestConfig.Providers))] 22 | public void ShouldComputeHash(ProviderType providerType) 23 | { 24 | // Given 25 | var dataStream = CreateDataStream(); 26 | 27 | // When 28 | 29 | byte[] hashValue; 30 | 31 | using (var hash = new Gost_R3411_94_HashAlgorithm(providerType)) 32 | { 33 | hashValue = hash.ComputeHash(dataStream); 34 | } 35 | 36 | // Then 37 | Assert.IsNotNull(hashValue); 38 | Assert.AreEqual(256, 8 * hashValue.Length); 39 | } 40 | 41 | private static Stream CreateDataStream() 42 | { 43 | // Некоторый поток байт 44 | 45 | return new MemoryStream(Encoding.UTF8.GetBytes("Some data to hash...")); 46 | } 47 | } 48 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Base/GostHashAlgorithm.cs: -------------------------------------------------------------------------------- 1 | using System.Security; 2 | using System.Security.Cryptography; 3 | 4 | using GostCryptography.Config; 5 | 6 | namespace GostCryptography.Base 7 | { 8 | /// 9 | /// Базовый класс для всех алгоритмов хэширования ГОСТ. 10 | /// 11 | public abstract class GostHashAlgorithm : HashAlgorithm, IGostAlgorithm 12 | { 13 | /// 14 | /// Конструктор. 15 | /// 16 | /// Размер хэш-кода в битах. 17 | /// 18 | /// По умолчанию использует криптографический провайдер, установленный в . 19 | /// 20 | [SecuritySafeCritical] 21 | protected GostHashAlgorithm(int hashSize) : this(GostCryptoConfig.ProviderType, hashSize) 22 | { 23 | } 24 | 25 | /// 26 | /// Конструктор. 27 | /// 28 | /// Тип криптографического провайдера. 29 | /// Размер хэш-кода в битах. 30 | [SecuritySafeCritical] 31 | protected GostHashAlgorithm(ProviderType providerType, int hashSize) 32 | { 33 | ProviderType = providerType; 34 | HashSizeValue = hashSize; 35 | } 36 | 37 | 38 | /// 39 | public ProviderType ProviderType { get; } 40 | 41 | /// 42 | public abstract string AlgorithmName { get; } 43 | } 44 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Base/GostHMAC.cs: -------------------------------------------------------------------------------- 1 | using System.Security; 2 | using System.Security.Cryptography; 3 | 4 | using GostCryptography.Config; 5 | 6 | namespace GostCryptography.Base 7 | { 8 | /// 9 | /// Базовый класс для всех реализаций Hash-based Message Authentication Code (HMAC) на базе алгоритмов ГОСТ. 10 | /// 11 | public abstract class GostHMAC : HMAC, IGostAlgorithm 12 | { 13 | /// 14 | /// Конструктор. 15 | /// 16 | /// Размер хэш-кода в битах. 17 | /// 18 | /// По умолчанию использует криптографический провайдер, установленный в . 19 | /// 20 | [SecuritySafeCritical] 21 | protected GostHMAC(int hashSize) : this(GostCryptoConfig.ProviderType, hashSize) 22 | { 23 | } 24 | 25 | /// 26 | /// Конструктор. 27 | /// 28 | /// Тип криптографического провайдера. 29 | /// Размер хэш-кода в битах. 30 | [SecuritySafeCritical] 31 | protected GostHMAC(ProviderType providerType, int hashSize) 32 | { 33 | ProviderType = providerType; 34 | HashSizeValue = hashSize; 35 | } 36 | 37 | 38 | /// 39 | public ProviderType ProviderType { get; } 40 | 41 | /// 42 | public abstract string AlgorithmName { get; } 43 | } 44 | } -------------------------------------------------------------------------------- /Source/GostCryptography.Tests/Gost_R3411/Gost_R3411_2012_256_HashAlgorithmTest.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | using System.Text; 3 | 4 | using GostCryptography.Base; 5 | using GostCryptography.Gost_R3411; 6 | 7 | using NUnit.Framework; 8 | 9 | namespace GostCryptography.Tests.Gost_R3411 10 | { 11 | /// 12 | /// Вычисление хэша в соответствии с ГОСТ Р 34.11-2012/256. 13 | /// 14 | /// 15 | /// Тест создает поток байт, вычисляет хэш в соответствии с ГОСТ Р 34.11-2012/256 и проверяет его корректность. 16 | /// 17 | [TestFixture(Description = "Вычисление хэша в соответствии с ГОСТ Р 34.11-2012/256")] 18 | public class Gost_R3411_2012_256_HashAlgorithmTest 19 | { 20 | [Test] 21 | [TestCaseSource(typeof(TestConfig), nameof(TestConfig.Providers))] 22 | public void ShouldComputeHash(ProviderType providerType) 23 | { 24 | // Given 25 | var dataStream = CreateDataStream(); 26 | 27 | // When 28 | 29 | byte[] hashValue; 30 | 31 | using (var hash = new Gost_R3411_2012_256_HashAlgorithm(providerType)) 32 | { 33 | hashValue = hash.ComputeHash(dataStream); 34 | } 35 | 36 | // Then 37 | Assert.IsNotNull(hashValue); 38 | Assert.AreEqual(256, 8 * hashValue.Length); 39 | } 40 | 41 | private static Stream CreateDataStream() 42 | { 43 | // Некоторый поток байт 44 | 45 | return new MemoryStream(Encoding.UTF8.GetBytes("Some data to hash...")); 46 | } 47 | } 48 | } -------------------------------------------------------------------------------- /Source/GostCryptography.Tests/Gost_R3411/Gost_R3411_2012_512_HashAlgorithmTest.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | using System.Text; 3 | 4 | using GostCryptography.Base; 5 | using GostCryptography.Gost_R3411; 6 | 7 | using NUnit.Framework; 8 | 9 | namespace GostCryptography.Tests.Gost_R3411 10 | { 11 | /// 12 | /// Вычисление хэша в соответствии с ГОСТ Р 34.11-2012/512. 13 | /// 14 | /// 15 | /// Тест создает поток байт, вычисляет хэш в соответствии с ГОСТ Р 34.11-2012/512 и проверяет его корректность. 16 | /// 17 | [TestFixture(Description = "Вычисление хэша в соответствии с ГОСТ Р 34.11-2012/512")] 18 | public class Gost_R3411_2012_512_HashAlgorithmTest 19 | { 20 | [Test] 21 | [TestCaseSource(typeof(TestConfig), nameof(TestConfig.Providers))] 22 | public void ShouldComputeHash(ProviderType providerType) 23 | { 24 | // Given 25 | var dataStream = CreateDataStream(); 26 | 27 | // When 28 | 29 | byte[] hashValue; 30 | 31 | using (var hash = new Gost_R3411_2012_512_HashAlgorithm(providerType)) 32 | { 33 | hashValue = hash.ComputeHash(dataStream); 34 | } 35 | 36 | // Then 37 | Assert.IsNotNull(hashValue); 38 | Assert.AreEqual(512, 8 * hashValue.Length); 39 | } 40 | 41 | private static Stream CreateDataStream() 42 | { 43 | // Некоторый поток байт 44 | 45 | return new MemoryStream(Encoding.UTF8.GetBytes("Some data to hash...")); 46 | } 47 | } 48 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Asn1/Ber/Asn1DiscreteCharSet.cs: -------------------------------------------------------------------------------- 1 | using GostCryptography.Properties; 2 | 3 | namespace GostCryptography.Asn1.Ber 4 | { 5 | public class Asn1DiscreteCharSet : Asn1CharSet 6 | { 7 | private readonly int[] _charSet; 8 | 9 | public Asn1DiscreteCharSet(string charSet) 10 | : base(charSet.Length) 11 | { 12 | _charSet = new int[charSet.Length]; 13 | 14 | for (var i = 0; i < _charSet.Length; i++) 15 | { 16 | _charSet[i] = charSet[i]; 17 | } 18 | } 19 | 20 | public Asn1DiscreteCharSet(int[] charSet) 21 | : base(charSet.Length) 22 | { 23 | _charSet = charSet; 24 | } 25 | 26 | public override int MaxValue 27 | { 28 | get { return _charSet[_charSet.Length - 1]; } 29 | } 30 | 31 | public override int GetCharAtIndex(int index) 32 | { 33 | if (index >= _charSet.Length) 34 | { 35 | throw ExceptionUtility.CryptographicException(Resources.Asn1ConsVioException, "Character index", index); 36 | } 37 | 38 | return _charSet[index]; 39 | } 40 | 41 | public override int GetCharIndex(int charValue) 42 | { 43 | var index = 0; 44 | 45 | while ((index < _charSet.Length) && (_charSet[index] != charValue)) 46 | { 47 | index++; 48 | } 49 | 50 | if (index >= _charSet.Length) 51 | { 52 | throw ExceptionUtility.CryptographicException(Resources.Asn1ConsVioException, "Character index", charValue); 53 | } 54 | 55 | return index; 56 | } 57 | } 58 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Base/GostKeyedHashAlgorithm.cs: -------------------------------------------------------------------------------- 1 | using System.Security; 2 | using System.Security.Cryptography; 3 | 4 | using GostCryptography.Config; 5 | 6 | namespace GostCryptography.Base 7 | { 8 | /// 9 | /// Базовый класс для всех алгоритмов хэширования ГОСТ на основе ключей. 10 | /// 11 | public abstract class GostKeyedHashAlgorithm : KeyedHashAlgorithm, IGostAlgorithm 12 | { 13 | /// 14 | /// Конструктор. 15 | /// 16 | /// Размер хэш-кода в битах. 17 | /// 18 | /// По умолчанию использует криптографический провайдер, установленный в . 19 | /// 20 | [SecuritySafeCritical] 21 | protected GostKeyedHashAlgorithm(int hashSize) : this(GostCryptoConfig.ProviderType, hashSize) 22 | { 23 | } 24 | 25 | /// 26 | /// Конструктор. 27 | /// 28 | /// Тип криптографического провайдера. 29 | /// Размер хэш-кода в битах. 30 | [SecuritySafeCritical] 31 | protected GostKeyedHashAlgorithm(ProviderType providerType, int hashSize) 32 | { 33 | ProviderType = providerType; 34 | HashSizeValue = hashSize; 35 | } 36 | 37 | 38 | /// 39 | public ProviderType ProviderType { get; } 40 | 41 | /// 42 | public abstract string AlgorithmName { get; } 43 | } 44 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Xml/GostKeyValue.cs: -------------------------------------------------------------------------------- 1 | using System.Security.Cryptography.Xml; 2 | using System.Xml; 3 | 4 | using GostCryptography.Base; 5 | 6 | namespace GostCryptography.Xml 7 | { 8 | /// 9 | /// Параметры открытого ключа цифровой подписи ГОСТ Р 34.10 элемента . 10 | /// 11 | public abstract class GostKeyValue : KeyInfoClause 12 | { 13 | /// 14 | /// URI пространства имен для XML-подписи ГОСТ Р 34.10. 15 | /// 16 | public const string XmlDsigNamespaceUrl = "urn:ietf:params:xml:ns:cpxmlsec"; 17 | 18 | 19 | /// 20 | /// Создает экземпляр класса с заданным публичным ключом. 21 | /// 22 | protected GostKeyValue(GostAsymmetricAlgorithm publicKey) 23 | { 24 | PublicKey = publicKey; 25 | } 26 | 27 | 28 | /// 29 | /// Открытый ключ. 30 | /// 31 | public GostAsymmetricAlgorithm PublicKey { get; set; } 32 | 33 | 34 | /// 35 | public override void LoadXml(XmlElement element) 36 | { 37 | if (element == null) 38 | { 39 | throw ExceptionUtility.ArgumentNull(nameof(element)); 40 | } 41 | 42 | PublicKey.FromXmlString(element.OuterXml); 43 | } 44 | 45 | /// 46 | public override XmlElement GetXml() 47 | { 48 | var document = new XmlDocument { PreserveWhitespace = true }; 49 | var element = document.CreateElement("KeyValue", SignedXml.XmlDsigNamespaceUrl); 50 | element.InnerXml = PublicKey.ToXmlString(false); 51 | return element; 52 | } 53 | } 54 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Reflection/CryptographyUtils.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Reflection; 3 | using System.Security.Cryptography; 4 | 5 | namespace GostCryptography.Reflection 6 | { 7 | static class CryptographyUtils 8 | { 9 | private static readonly object ObjToHashAlgorithmMethodSync = new object(); 10 | private static volatile MethodInfo _objToHashAlgorithmMethod; 11 | 12 | 13 | public static HashAlgorithm ObjToHashAlgorithm(object hashAlg) 14 | { 15 | if (hashAlg == null) 16 | { 17 | throw ExceptionUtility.ArgumentNull(nameof(hashAlg)); 18 | } 19 | 20 | HashAlgorithm hashAlgorithm = null; 21 | 22 | if (_objToHashAlgorithmMethod == null) 23 | { 24 | lock (ObjToHashAlgorithmMethodSync) 25 | { 26 | if (_objToHashAlgorithmMethod == null) 27 | { 28 | var utilsType = Type.GetType("System.Security.Cryptography.Utils"); 29 | 30 | if (utilsType != null) 31 | { 32 | _objToHashAlgorithmMethod = utilsType.GetMethod("ObjToHashAlgorithm", BindingFlags.Static | BindingFlags.NonPublic, null, new[] { typeof(object) }, null); 33 | } 34 | } 35 | } 36 | } 37 | 38 | if (_objToHashAlgorithmMethod != null) 39 | { 40 | try 41 | { 42 | hashAlgorithm = _objToHashAlgorithmMethod.Invoke(null, new[] { hashAlg }) as HashAlgorithm; 43 | } 44 | catch (TargetInvocationException exception) 45 | { 46 | if (exception.InnerException != null) 47 | { 48 | throw exception.InnerException; 49 | } 50 | 51 | throw; 52 | } 53 | } 54 | 55 | return hashAlgorithm; 56 | } 57 | } 58 | } -------------------------------------------------------------------------------- /GostCryptography.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.29512.175 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GostCryptography", "Source\GostCryptography\GostCryptography.csproj", "{EE8D8C45-326A-4D71-84D0-DC71B18B22A7}" 7 | EndProject 8 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GostCryptography.Tests", "Source\GostCryptography.Tests\GostCryptography.Tests.csproj", "{95439866-6A37-4343-BBD5-8C1625E11A6F}" 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | Debug|Any CPU = Debug|Any CPU 13 | Release|Any CPU = Release|Any CPU 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {EE8D8C45-326A-4D71-84D0-DC71B18B22A7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 17 | {EE8D8C45-326A-4D71-84D0-DC71B18B22A7}.Debug|Any CPU.Build.0 = Debug|Any CPU 18 | {EE8D8C45-326A-4D71-84D0-DC71B18B22A7}.Release|Any CPU.ActiveCfg = Release|Any CPU 19 | {EE8D8C45-326A-4D71-84D0-DC71B18B22A7}.Release|Any CPU.Build.0 = Release|Any CPU 20 | {95439866-6A37-4343-BBD5-8C1625E11A6F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 21 | {95439866-6A37-4343-BBD5-8C1625E11A6F}.Debug|Any CPU.Build.0 = Debug|Any CPU 22 | {95439866-6A37-4343-BBD5-8C1625E11A6F}.Release|Any CPU.ActiveCfg = Release|Any CPU 23 | {95439866-6A37-4343-BBD5-8C1625E11A6F}.Release|Any CPU.Build.0 = Release|Any CPU 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | SolutionGuid = {931A6A65-5EA6-4213-9740-14B08A622AEF} 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /Source/GostCryptography/Asn1/Gost/PublicKey/SubjectPublicKeyInfo.cs: -------------------------------------------------------------------------------- 1 | using GostCryptography.Asn1.Ber; 2 | using GostCryptography.Properties; 3 | 4 | namespace GostCryptography.Asn1.Gost.PublicKey 5 | { 6 | public sealed class SubjectPublicKeyInfo : Asn1Type 7 | { 8 | public AlgorithmIdentifier Algorithm { get; set; } 9 | 10 | public Asn1BitString SubjectPublicKey { get; set; } 11 | 12 | 13 | public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength) 14 | { 15 | var elemLength = explicitTagging ? MatchTag(buffer, Asn1Tag.Sequence) : implicitLength; 16 | 17 | Algorithm = null; 18 | SubjectPublicKey = null; 19 | 20 | var context = new Asn1BerDecodeContext(buffer, elemLength); 21 | var parsedLen = new IntHolder(); 22 | 23 | if (!context.MatchElemTag(0, 0x20, 0x10, parsedLen, false)) 24 | { 25 | throw ExceptionUtility.CryptographicException(Resources.Asn1MissingRequiredException, buffer.ByteCount); 26 | } 27 | 28 | Algorithm = new AlgorithmIdentifier(); 29 | Algorithm.Decode(buffer, true, parsedLen.Value); 30 | 31 | if (!context.MatchElemTag(0, 0, 3, parsedLen, false)) 32 | { 33 | throw ExceptionUtility.CryptographicException(Resources.Asn1MissingRequiredException, buffer.ByteCount); 34 | } 35 | 36 | SubjectPublicKey = new Asn1BitString(); 37 | SubjectPublicKey.Decode(buffer, true, parsedLen.Value); 38 | } 39 | 40 | public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging) 41 | { 42 | var len = 0; 43 | len += SubjectPublicKey.Encode(buffer, true); 44 | len += Algorithm.Encode(buffer, true); 45 | 46 | if (explicitTagging) 47 | { 48 | len += buffer.EncodeTagAndLength(Asn1Tag.Sequence, len); 49 | } 50 | 51 | return len; 52 | } 53 | } 54 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Asn1/Gost/Gost_28147_89/Gost_28147_89_Params.cs: -------------------------------------------------------------------------------- 1 | using GostCryptography.Asn1.Ber; 2 | using GostCryptography.Properties; 3 | 4 | namespace GostCryptography.Asn1.Gost.Gost_28147_89 5 | { 6 | public sealed class Gost_28147_89_Params : Asn1Type 7 | { 8 | public Asn1ObjectIdentifier EncryptionParamSet { get; private set; } 9 | 10 | public Gost_28147_89_Iv Iv { get; private set; } 11 | 12 | 13 | public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength) 14 | { 15 | var elemLength = explicitTagging ? MatchTag(buffer, Asn1Tag.Sequence) : implicitLength; 16 | 17 | EncryptionParamSet = null; 18 | Iv = null; 19 | 20 | var context = new Asn1BerDecodeContext(buffer, elemLength); 21 | var parsedLen = new IntHolder(); 22 | 23 | if (!context.MatchElemTag(0, 0, OctetStringTypeCode, parsedLen, false)) 24 | { 25 | throw ExceptionUtility.CryptographicException(Resources.Asn1MissingRequiredException, buffer.ByteCount); 26 | } 27 | 28 | Iv = new Gost_28147_89_Iv(); 29 | Iv.Decode(buffer, true, parsedLen.Value); 30 | 31 | if (!context.MatchElemTag(0, 0, ObjectIdentifierTypeCode, parsedLen, false)) 32 | { 33 | throw ExceptionUtility.CryptographicException(Resources.Asn1MissingRequiredException, buffer.ByteCount); 34 | } 35 | 36 | EncryptionParamSet = new Asn1ObjectIdentifier(); 37 | EncryptionParamSet.Decode(buffer, true, parsedLen.Value); 38 | } 39 | 40 | public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging) 41 | { 42 | var len = 0; 43 | 44 | len += EncryptionParamSet.Encode(buffer, true); 45 | len += Iv.Encode(buffer, true); 46 | 47 | if (explicitTagging) 48 | { 49 | len += buffer.EncodeTagAndLength(Asn1Tag.Sequence, len); 50 | } 51 | 52 | return len; 53 | } 54 | } 55 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Asn1/Ber/Asn1RelativeOid.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | using GostCryptography.Properties; 4 | 5 | namespace GostCryptography.Asn1.Ber 6 | { 7 | [Serializable] 8 | public class Asn1RelativeOid : Asn1ObjectIdentifier 9 | { 10 | public new static readonly Asn1Tag Tag = new Asn1Tag(0, 0, RelativeOidTypeCode); 11 | 12 | 13 | public Asn1RelativeOid() 14 | { 15 | } 16 | 17 | public Asn1RelativeOid(OidValue oidValue) 18 | : base(oidValue) 19 | { 20 | } 21 | 22 | 23 | public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength) 24 | { 25 | var len = explicitTagging ? MatchTag(buffer, Tag) : implicitLength; 26 | OidValue = OidValue.FromArray(buffer.DecodeRelOidContents(len)); 27 | buffer.TypeCode = RelativeOidTypeCode; 28 | } 29 | 30 | public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging) 31 | { 32 | if (OidValue.Items.Length < 1) 33 | { 34 | throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidObjectIdException); 35 | } 36 | 37 | var len = 0; 38 | 39 | for (var i = OidValue.Items.Length - 1; i >= 0; i--) 40 | { 41 | len += buffer.EncodeIdentifier(OidValue.Items[i]); 42 | } 43 | 44 | if (explicitTagging) 45 | { 46 | len += buffer.EncodeTagAndLength(Tag, len); 47 | } 48 | 49 | return len; 50 | } 51 | 52 | public override void Encode(Asn1BerOutputStream outs, bool explicitTagging) 53 | { 54 | var len = 0; 55 | 56 | foreach (var i in OidValue.Items) 57 | { 58 | len += Asn1RunTime.GetIdentBytesCount(i); 59 | } 60 | 61 | if (explicitTagging) 62 | { 63 | outs.EncodeTag(Tag); 64 | } 65 | 66 | outs.EncodeLength(len); 67 | 68 | foreach (var i in OidValue.Items) 69 | { 70 | outs.EncodeIdentifier(i); 71 | } 72 | } 73 | } 74 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Base/GostAsymmetricAlgorithm.cs: -------------------------------------------------------------------------------- 1 | using System.Security.Cryptography; 2 | 3 | namespace GostCryptography.Base 4 | { 5 | /// 6 | /// Базовый класс для всех асимметричных алгоритмов ГОСТ. 7 | /// 8 | public abstract class GostAsymmetricAlgorithm : AsymmetricAlgorithm, IGostAlgorithm 9 | { 10 | /// 11 | /// Конструктор. 12 | /// 13 | /// Тип криптографического провайдера. 14 | /// Размер ключа в битах. 15 | protected GostAsymmetricAlgorithm(ProviderType providerType, int keySize) 16 | { 17 | ProviderType = providerType; 18 | KeySizeValue = keySize; 19 | LegalKeySizesValue = new[] { new KeySizes(keySize, keySize, 0) }; 20 | } 21 | 22 | 23 | /// 24 | public ProviderType ProviderType { get; } 25 | 26 | /// 27 | public abstract string AlgorithmName { get; } 28 | 29 | 30 | /// 31 | /// Вычисляет цифровую подпись. 32 | /// 33 | public abstract byte[] CreateSignature(byte[] hash); 34 | 35 | /// 36 | /// Проверяет цифровую подпись. 37 | /// 38 | public abstract bool VerifySignature(byte[] hash, byte[] signature); 39 | 40 | 41 | /// 42 | /// Создает экземпляр . 43 | /// 44 | public abstract GostHashAlgorithm CreateHashAlgorithm(); 45 | 46 | 47 | /// 48 | /// Создает экземпляр . 49 | /// 50 | /// 51 | public abstract GostKeyExchangeFormatter CreateKeyExchangeFormatter(); 52 | 53 | /// 54 | /// Создает экземпляр . 55 | /// 56 | public abstract GostKeyExchangeDeformatter CreateKeyExchangeDeformatter(); 57 | } 58 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Asn1/Gost/Gost_28147_89/Gost_28147_89_KeyWrap.cs: -------------------------------------------------------------------------------- 1 | using GostCryptography.Asn1.Ber; 2 | using GostCryptography.Properties; 3 | 4 | namespace GostCryptography.Asn1.Gost.Gost_28147_89 5 | { 6 | public sealed class Gost_28147_89_KeyWrap : Asn1Type 7 | { 8 | public Gost_28147_89_EncryptedKey EncryptedKey { get; set; } 9 | 10 | public Gost_28147_89_KeyWrapParams EncryptedParams { get; set; } 11 | 12 | 13 | public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength) 14 | { 15 | var elemLength = explicitTagging ? MatchTag(buffer, Asn1Tag.Sequence) : implicitLength; 16 | 17 | EncryptedKey = null; 18 | EncryptedParams = null; 19 | 20 | var context = new Asn1BerDecodeContext(buffer, elemLength); 21 | var parsedLen = new IntHolder(); 22 | 23 | if (!context.MatchElemTag(0, 0x20, SequenceTypeCode, parsedLen, false)) 24 | { 25 | throw ExceptionUtility.CryptographicException(Resources.Asn1MissingRequiredException, buffer.ByteCount); 26 | } 27 | 28 | EncryptedKey = new Gost_28147_89_EncryptedKey(); 29 | EncryptedKey.Decode(buffer, true, parsedLen.Value); 30 | 31 | if (!context.MatchElemTag(0, 0x20, SequenceTypeCode, parsedLen, false)) 32 | { 33 | throw ExceptionUtility.CryptographicException(Resources.Asn1MissingRequiredException, buffer.ByteCount); 34 | } 35 | 36 | EncryptedParams = new Gost_28147_89_KeyWrapParams(); 37 | EncryptedParams.Decode(buffer, true, parsedLen.Value); 38 | } 39 | 40 | public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging) 41 | { 42 | var len = 0; 43 | len += EncryptedParams.Encode(buffer, true); 44 | len += EncryptedKey.Encode(buffer, true); 45 | 46 | if (explicitTagging) 47 | { 48 | len += buffer.EncodeTagAndLength(Asn1Tag.Sequence, len); 49 | } 50 | 51 | return len; 52 | } 53 | } 54 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Gost_R3411/Gost_R3411_2012_256_HashAlgorithm.cs: -------------------------------------------------------------------------------- 1 | using System.Security; 2 | 3 | using GostCryptography.Base; 4 | using GostCryptography.Native; 5 | 6 | namespace GostCryptography.Gost_R3411 7 | { 8 | /// 9 | /// Реализация алгоритма хэширования ГОСТ Р 34.11-2012/256. 10 | /// 11 | public sealed class Gost_R3411_2012_256_HashAlgorithm : Gost_R3411_HashAlgorithm 12 | { 13 | /// 14 | /// Размер хэша ГОСТ Р 34.11-2012/256. 15 | /// 16 | public const int DefaultHashSizeValue = 256; 17 | 18 | /// 19 | /// Наименование алгоритма хэширования ГОСТ Р 34.11-2012/256. 20 | /// 21 | public const string AlgorithmNameValue = "urn:ietf:params:xml:ns:cpxmlsec:algorithms:gostr34112012-256"; 22 | 23 | /// 24 | /// Известные наименования алгоритма хэширования ГОСТ Р 34.11-2012/256. 25 | /// 26 | public static readonly string[] KnownAlgorithmNames = { AlgorithmNameValue }; 27 | 28 | 29 | /// 30 | [SecuritySafeCritical] 31 | public Gost_R3411_2012_256_HashAlgorithm() : base(DefaultHashSizeValue) 32 | { 33 | } 34 | 35 | /// 36 | [SecuritySafeCritical] 37 | public Gost_R3411_2012_256_HashAlgorithm(ProviderType providerType) : base(providerType, DefaultHashSizeValue) 38 | { 39 | } 40 | 41 | [SecurityCritical] 42 | internal Gost_R3411_2012_256_HashAlgorithm(ProviderType providerType, SafeProvHandleImpl providerHandle) : base(providerType, providerHandle, DefaultHashSizeValue) 43 | { 44 | } 45 | 46 | 47 | /// 48 | public override string AlgorithmName => AlgorithmNameValue; 49 | 50 | 51 | /// 52 | [SecurityCritical] 53 | protected override SafeHashHandleImpl CreateHashHandle(SafeProvHandleImpl providerHandle) 54 | { 55 | return CryptoApiHelper.CreateHash_3411_2012_256(providerHandle); 56 | } 57 | } 58 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Gost_R3411/Gost_R3411_2012_512_HashAlgorithm.cs: -------------------------------------------------------------------------------- 1 | using System.Security; 2 | 3 | using GostCryptography.Base; 4 | using GostCryptography.Native; 5 | 6 | namespace GostCryptography.Gost_R3411 7 | { 8 | /// 9 | /// Реализация алгоритма хэширования ГОСТ Р 34.11-2012/512. 10 | /// 11 | public sealed class Gost_R3411_2012_512_HashAlgorithm : Gost_R3411_HashAlgorithm 12 | { 13 | /// 14 | /// Размер хэша ГОСТ Р 34.11-2012/512. 15 | /// 16 | public const int DefaultHashSizeValue = 512; 17 | 18 | /// 19 | /// Наименование алгоритма хэширования ГОСТ Р 34.11-2012/512. 20 | /// 21 | public const string AlgorithmNameValue = "urn:ietf:params:xml:ns:cpxmlsec:algorithms:gostr34112012-512"; 22 | 23 | /// 24 | /// Известные наименования алгоритма хэширования ГОСТ Р 34.11-2012/512. 25 | /// 26 | public static readonly string[] KnownAlgorithmNames = { AlgorithmNameValue }; 27 | 28 | 29 | /// 30 | [SecuritySafeCritical] 31 | public Gost_R3411_2012_512_HashAlgorithm() : base(DefaultHashSizeValue) 32 | { 33 | } 34 | 35 | /// 36 | [SecuritySafeCritical] 37 | public Gost_R3411_2012_512_HashAlgorithm(ProviderType providerType) : base(providerType, DefaultHashSizeValue) 38 | { 39 | } 40 | 41 | [SecurityCritical] 42 | internal Gost_R3411_2012_512_HashAlgorithm(ProviderType providerType, SafeProvHandleImpl providerHandle) : base(providerType, providerHandle, DefaultHashSizeValue) 43 | { 44 | } 45 | 46 | 47 | /// 48 | public override string AlgorithmName => AlgorithmNameValue; 49 | 50 | 51 | /// 52 | [SecurityCritical] 53 | protected override SafeHashHandleImpl CreateHashHandle(SafeProvHandleImpl providerHandle) 54 | { 55 | return CryptoApiHelper.CreateHash_3411_2012_512(providerHandle); 56 | } 57 | } 58 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Native/SafeProvHandleImpl.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | using System.Security; 5 | 6 | using GostCryptography.Base; 7 | 8 | using Microsoft.Win32.SafeHandles; 9 | 10 | namespace GostCryptography.Native 11 | { 12 | /// 13 | /// Дескриптор криптографического провайдера. 14 | /// 15 | [SecurityCritical] 16 | public sealed class SafeProvHandleImpl : SafeHandleZeroOrMinusOneIsInvalid 17 | { 18 | public static SafeProvHandleImpl InvalidHandle => new SafeProvHandleImpl(IntPtr.Zero); 19 | 20 | 21 | public SafeProvHandleImpl() : base(true) 22 | { 23 | } 24 | 25 | public SafeProvHandleImpl(IntPtr handle) : base(true) 26 | { 27 | SetHandle(handle); 28 | } 29 | 30 | public SafeProvHandleImpl(IntPtr handle, bool addref) : base(true) 31 | { 32 | if (!addref) 33 | { 34 | SetHandle(handle); 35 | } 36 | else 37 | { 38 | bool success; 39 | int errorCode; 40 | 41 | // Обеспечивает атомарность блока finally 42 | RuntimeHelpers.PrepareConstrainedRegions(); 43 | 44 | try { } 45 | finally 46 | { 47 | success = CryptoApi.CryptContextAddRef(handle, null, 0); 48 | errorCode = Marshal.GetLastWin32Error(); 49 | 50 | if (success) 51 | { 52 | SetHandle(handle); 53 | } 54 | } 55 | 56 | if (!success) 57 | { 58 | throw ExceptionUtility.CryptographicException(errorCode); 59 | } 60 | } 61 | } 62 | 63 | 64 | public bool DeleteOnClose { get; set; } 65 | 66 | 67 | [SecurityCritical] 68 | protected override bool ReleaseHandle() 69 | { 70 | if (DeleteOnClose) 71 | { 72 | CryptoApi.CryptSetProvParam2(handle, Constants.PP_DELETE_KEYSET, null, 0); 73 | } 74 | else 75 | { 76 | CryptoApi.CryptReleaseContext(handle, 0); 77 | } 78 | 79 | return true; 80 | } 81 | } 82 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Asn1/Gost/GostAsn1Choice.cs: -------------------------------------------------------------------------------- 1 | using GostCryptography.Asn1.Ber; 2 | using GostCryptography.Properties; 3 | 4 | namespace GostCryptography.Asn1.Gost 5 | { 6 | public abstract class GostAsn1Choice : Asn1Choice 7 | { 8 | private const byte Null = 1; 9 | private const byte Params = 2; 10 | 11 | 12 | protected abstract short TagForm { get; } 13 | protected abstract int TagIdCode { get; } 14 | protected abstract Asn1Type CreateParams(); 15 | 16 | 17 | public override string ElemName 18 | { 19 | get 20 | { 21 | switch (ChoiceId) 22 | { 23 | case Null: 24 | return "null_"; 25 | case Params: 26 | return "params_"; 27 | } 28 | 29 | return "UNDEFINED"; 30 | } 31 | } 32 | 33 | 34 | public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength) 35 | { 36 | var tag = new Asn1Tag(); 37 | buffer.Mark(); 38 | 39 | var num = buffer.DecodeTagAndLength(tag); 40 | 41 | if (tag.Equals(0, 0, NullTypeCode)) 42 | { 43 | buffer.Reset(); 44 | 45 | SetElement(Null, new NullParams()); 46 | Element.Decode(buffer, true, num); 47 | } 48 | else 49 | { 50 | if (!tag.Equals(0, TagForm, TagIdCode)) 51 | { 52 | throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidChoiceOptionTagException, tag, buffer.ByteCount); 53 | } 54 | 55 | buffer.Reset(); 56 | 57 | SetElement(Params, CreateParams()); 58 | Element.Decode(buffer, true, num); 59 | } 60 | } 61 | 62 | public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging) 63 | { 64 | switch (ChoiceId) 65 | { 66 | case Null: 67 | return GetElement().Encode(buffer, true); 68 | case Params: 69 | return GetElement().Encode(buffer, true); 70 | } 71 | 72 | throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidChoiceOptionException); 73 | } 74 | } 75 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Asn1/Ber/Asn1Enumerated.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace GostCryptography.Asn1.Ber 4 | { 5 | [Serializable] 6 | public abstract class Asn1Enumerated : Asn1Type 7 | { 8 | public const int Undefined = -999; 9 | public static readonly Asn1Tag Tag = new Asn1Tag(0, 0, EnumeratedTypeCode); 10 | 11 | [NonSerialized] 12 | public int Value; 13 | 14 | public Asn1Enumerated() 15 | { 16 | Value = Undefined; 17 | } 18 | 19 | public Asn1Enumerated(int value) 20 | { 21 | Value = value; 22 | } 23 | 24 | public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength) 25 | { 26 | var length = explicitTagging ? MatchTag(buffer, Tag) : implicitLength; 27 | Value = (int)Asn1RunTime.DecodeIntValue(buffer, length, true); 28 | buffer.TypeCode = EnumeratedTypeCode; 29 | } 30 | 31 | public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging) 32 | { 33 | var len = buffer.EncodeIntValue(Value); 34 | 35 | if (explicitTagging) 36 | { 37 | len += buffer.EncodeTagAndLength(Tag, len); 38 | } 39 | 40 | return len; 41 | } 42 | 43 | public override void Encode(Asn1BerOutputStream outs, bool explicitTagging) 44 | { 45 | if (explicitTagging) 46 | { 47 | outs.EncodeTag(Tag); 48 | } 49 | 50 | outs.EncodeIntValue(Value, true); 51 | } 52 | 53 | public virtual bool Equals(int value) 54 | { 55 | return (Value == value); 56 | } 57 | 58 | public override bool Equals(object value) 59 | { 60 | var enumerated = value as Asn1Enumerated; 61 | 62 | return (enumerated != null && Value == enumerated.Value); 63 | } 64 | 65 | public override int GetHashCode() 66 | { 67 | return Value.GetHashCode(); 68 | } 69 | 70 | public virtual int ParseValue(string value) 71 | { 72 | return -1; 73 | } 74 | 75 | public override string ToString() 76 | { 77 | return null; 78 | } 79 | } 80 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Asn1/Ber/Asn1OutputStream.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | 3 | using GostCryptography.Properties; 4 | 5 | namespace GostCryptography.Asn1.Ber 6 | { 7 | public abstract class Asn1OutputStream : Stream 8 | { 9 | protected readonly Stream OutputStream; 10 | 11 | public Asn1OutputStream(Stream outputStream) 12 | { 13 | OutputStream = outputStream; 14 | } 15 | 16 | public override bool CanRead 17 | { 18 | get { return false; } 19 | } 20 | 21 | public override bool CanSeek 22 | { 23 | get { return OutputStream.CanSeek; } 24 | } 25 | 26 | public override bool CanWrite 27 | { 28 | get { return OutputStream.CanWrite; } 29 | } 30 | 31 | public override long Length 32 | { 33 | get { return OutputStream.Length; } 34 | } 35 | 36 | public override long Position 37 | { 38 | get { return OutputStream.Position; } 39 | set { OutputStream.Position = value; } 40 | } 41 | 42 | public override void Close() 43 | { 44 | OutputStream.Close(); 45 | } 46 | 47 | public override void Flush() 48 | { 49 | OutputStream.Flush(); 50 | } 51 | 52 | public override int Read(byte[] buffer, int offset, int count) 53 | { 54 | throw ExceptionUtility.NotSupported(Resources.Asn1ReadOutputStreamNotSupported); 55 | } 56 | 57 | public override long Seek(long offset, SeekOrigin origin) 58 | { 59 | return OutputStream.Seek(offset, origin); 60 | } 61 | 62 | public override void SetLength(long value) 63 | { 64 | OutputStream.SetLength(value); 65 | } 66 | 67 | public virtual void Write(byte[] b) 68 | { 69 | OutputStream.Write(b, 0, b.Length); 70 | } 71 | 72 | public override void Write(byte[] b, int off, int len) 73 | { 74 | OutputStream.Write(b, off, len); 75 | } 76 | 77 | public override void WriteByte(byte b) 78 | { 79 | OutputStream.WriteByte(b); 80 | } 81 | 82 | public virtual void WriteByte(int b) 83 | { 84 | OutputStream.WriteByte((byte)b); 85 | } 86 | } 87 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Gost_R3411/Gost_R3411_94_PRF.cs: -------------------------------------------------------------------------------- 1 | using System.Security; 2 | 3 | using GostCryptography.Base; 4 | using GostCryptography.Gost_28147_89; 5 | 6 | namespace GostCryptography.Gost_R3411 7 | { 8 | /// 9 | /// Реализация PRF на базе алгоритма хэширования ГОСТ Р 34.11-94. 10 | /// 11 | public sealed class Gost_R3411_94_PRF : Gost_R3411_PRF 12 | { 13 | /// 14 | /// Наименование алгоритма PRF на базе ГОСТ Р 34.11-94 для использования в протоколе WS-Trust. 15 | /// 16 | public const string WsTrustAlgorithmNameValue = "http://docs.oasis-open.org/ws-sx/ws-trust/200512/CK/PGOSTR3411"; 17 | 18 | /// 19 | /// Наименование алгоритма PRF на базе ГОСТ Р 34.11-94 для использования в протоколах на базе WS-SecureConversation. 20 | /// 21 | public const string WsSecureConversationAlgorithmNameValue = "http://docs.oasis-open.org/ws-sx/ws-secureconversation/200512/dk/p_gostr3411"; 22 | 23 | /// 24 | /// Известные наименования алгоритма PRF на базе ГОСТ Р 34.11-94. 25 | /// 26 | public static readonly string[] KnownAlgorithmNames = { WsTrustAlgorithmNameValue, WsSecureConversationAlgorithmNameValue }; 27 | 28 | 29 | /// 30 | [SecuritySafeCritical] 31 | public Gost_R3411_94_PRF(Gost_28147_89_SymmetricAlgorithmBase key, byte[] label, byte[] seed) : base(key, label, seed) 32 | { 33 | } 34 | 35 | /// 36 | [SecuritySafeCritical] 37 | public Gost_R3411_94_PRF(ProviderType providerType, byte[] key, byte[] label, byte[] seed) : base(providerType, key, label, seed) 38 | { 39 | } 40 | 41 | 42 | /// 43 | public override string AlgorithmName => WsTrustAlgorithmNameValue; 44 | 45 | 46 | /// 47 | [SecuritySafeCritical] 48 | protected override Gost_R3411_94_HMAC CreateHMAC(Gost_28147_89_SymmetricAlgorithm key) 49 | { 50 | return new Gost_R3411_94_HMAC(key); 51 | } 52 | } 53 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Gost_R3411/Gost_R3411_2012_256_HMAC.cs: -------------------------------------------------------------------------------- 1 | using System.Security; 2 | 3 | using GostCryptography.Base; 4 | using GostCryptography.Gost_28147_89; 5 | using GostCryptography.Native; 6 | 7 | namespace GostCryptography.Gost_R3411 8 | { 9 | /// 10 | /// Реализация HMAC на базе алгоритма хэширования ГОСТ Р 34.11-2012/256. 11 | /// 12 | public sealed class Gost_R3411_2012_256_HMAC : Gost_R3411_HMAC 13 | { 14 | /// 15 | /// Наименование алгоритма HMAC на базе ГОСТ Р 34.11-2012/256. 16 | /// 17 | public const string AlgorithmNameValue = "urn:ietf:params:xml:ns:cpxmlsec:algorithms:hmac-gostr34112012-256"; 18 | 19 | /// 20 | /// Известные наименования алгоритма HMAC на базе ГОСТ Р 34.11-2012/256. 21 | /// 22 | public static readonly string[] KnownAlgorithmNames = { AlgorithmNameValue }; 23 | 24 | 25 | /// 26 | [SecuritySafeCritical] 27 | public Gost_R3411_2012_256_HMAC() : base(Gost_R3411_2012_256_HashAlgorithm.DefaultHashSizeValue) 28 | { 29 | } 30 | 31 | /// 32 | [SecuritySafeCritical] 33 | public Gost_R3411_2012_256_HMAC(ProviderType providerType) : base(providerType, Gost_R3411_2012_256_HashAlgorithm.DefaultHashSizeValue) 34 | { 35 | } 36 | 37 | /// 38 | [SecuritySafeCritical] 39 | public Gost_R3411_2012_256_HMAC(Gost_28147_89_SymmetricAlgorithmBase keyAlgorithm) : base(keyAlgorithm, Gost_R3411_2012_256_HashAlgorithm.DefaultHashSizeValue) 40 | { 41 | } 42 | 43 | 44 | /// 45 | public override string AlgorithmName => AlgorithmNameValue; 46 | 47 | 48 | /// 49 | [SecuritySafeCritical] 50 | protected override SafeHashHandleImpl CreateHashHMAC(ProviderType providerType, SafeProvHandleImpl providerHandle, SafeKeyHandleImpl symKeyHandle) 51 | { 52 | return CryptoApiHelper.CreateHashHMAC_2012_256(providerType, providerHandle, symKeyHandle); 53 | } 54 | } 55 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Gost_R3411/Gost_R3411_2012_512_HMAC.cs: -------------------------------------------------------------------------------- 1 | using System.Security; 2 | 3 | using GostCryptography.Base; 4 | using GostCryptography.Gost_28147_89; 5 | using GostCryptography.Native; 6 | 7 | namespace GostCryptography.Gost_R3411 8 | { 9 | /// 10 | /// Реализация HMAC на базе алгоритма хэширования ГОСТ Р 34.11-2012/512. 11 | /// 12 | public sealed class Gost_R3411_2012_512_HMAC : Gost_R3411_HMAC 13 | { 14 | /// 15 | /// Наименование алгоритма HMAC на базе ГОСТ Р 34.11-2012/512. 16 | /// 17 | public const string AlgorithmNameValue = "urn:ietf:params:xml:ns:cpxmlsec:algorithms:hmac-gostr34112012-512"; 18 | 19 | /// 20 | /// Известные наименования алгоритма HMAC на базе ГОСТ Р 34.11-2012/512. 21 | /// 22 | public static readonly string[] KnownAlgorithmNames = { AlgorithmNameValue }; 23 | 24 | 25 | /// 26 | [SecuritySafeCritical] 27 | public Gost_R3411_2012_512_HMAC() : base(Gost_R3411_2012_512_HashAlgorithm.DefaultHashSizeValue) 28 | { 29 | } 30 | 31 | /// 32 | [SecuritySafeCritical] 33 | public Gost_R3411_2012_512_HMAC(ProviderType providerType) : base(providerType, Gost_R3411_2012_512_HashAlgorithm.DefaultHashSizeValue) 34 | { 35 | } 36 | 37 | /// 38 | [SecuritySafeCritical] 39 | public Gost_R3411_2012_512_HMAC(Gost_28147_89_SymmetricAlgorithmBase keyAlgorithm) : base(keyAlgorithm, Gost_R3411_2012_512_HashAlgorithm.DefaultHashSizeValue) 40 | { 41 | } 42 | 43 | 44 | /// 45 | public override string AlgorithmName => AlgorithmNameValue; 46 | 47 | 48 | /// 49 | [SecuritySafeCritical] 50 | protected override SafeHashHandleImpl CreateHashHMAC(ProviderType providerType, SafeProvHandleImpl providerHandle, SafeKeyHandleImpl symKeyHandle) 51 | { 52 | return CryptoApiHelper.CreateHashHMAC_2012_512(providerType, providerHandle, symKeyHandle); 53 | } 54 | } 55 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Asn1/Gost/Gost_R3410/Gost_R3410_KeyTransport.cs: -------------------------------------------------------------------------------- 1 | using GostCryptography.Asn1.Ber; 2 | using GostCryptography.Asn1.Gost.Gost_28147_89; 3 | using GostCryptography.Properties; 4 | 5 | namespace GostCryptography.Asn1.Gost.Gost_R3410 6 | { 7 | public sealed class Gost_R3410_KeyTransport : Asn1Type 8 | { 9 | public Gost_28147_89_EncryptedKey SessionEncryptedKey { get; set; } 10 | 11 | public Gost_R3410_TransportParams TransportParams { get; set; } 12 | 13 | 14 | public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength) 15 | { 16 | var elemLength = explicitTagging ? MatchTag(buffer, Asn1Tag.Sequence) : implicitLength; 17 | 18 | SessionEncryptedKey = null; 19 | TransportParams = null; 20 | 21 | var context = new Asn1BerDecodeContext(buffer, elemLength); 22 | var parsedLen = new IntHolder(); 23 | 24 | if (!context.MatchElemTag(0, 0x20, SequenceTypeCode, parsedLen, false)) 25 | { 26 | throw ExceptionUtility.CryptographicException(Resources.Asn1MissingRequiredException, buffer.ByteCount); 27 | } 28 | 29 | SessionEncryptedKey = new Gost_28147_89_EncryptedKey(); 30 | SessionEncryptedKey.Decode(buffer, true, parsedLen.Value); 31 | 32 | if (context.MatchElemTag(0x80, 0x20, EocTypeCode, parsedLen, true)) 33 | { 34 | TransportParams = new Gost_R3410_TransportParams(); 35 | TransportParams.Decode(buffer, false, parsedLen.Value); 36 | } 37 | } 38 | 39 | public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging) 40 | { 41 | var len = 0; 42 | 43 | if (TransportParams != null) 44 | { 45 | var tpLength = TransportParams.Encode(buffer, false); 46 | 47 | len += tpLength; 48 | len += buffer.EncodeTagAndLength(0x80, 0x20, EocTypeCode, tpLength); 49 | } 50 | 51 | len += SessionEncryptedKey.Encode(buffer, true); 52 | 53 | if (explicitTagging) 54 | { 55 | len += buffer.EncodeTagAndLength(Asn1Tag.Sequence, len); 56 | } 57 | 58 | return len; 59 | } 60 | } 61 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Asn1/Ber/Asn1OpenExt.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Text; 4 | 5 | namespace GostCryptography.Asn1.Ber 6 | { 7 | [Serializable] 8 | public class Asn1OpenExt : Asn1Type 9 | { 10 | [NonSerialized] 11 | public ArrayList Value = new ArrayList(); 12 | 13 | public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength) 14 | { 15 | DecodeComponent(buffer); 16 | } 17 | 18 | public virtual void DecodeComponent(Asn1BerDecodeBuffer buffer) 19 | { 20 | var type = new Asn1OpenType(); 21 | type.Decode(buffer, false, 0); 22 | Value.Add(type); 23 | } 24 | 25 | public virtual void DecodeEventComponent(Asn1BerDecodeBuffer buffer) 26 | { 27 | buffer.InvokeStartElement("...", -1); 28 | 29 | var type = new Asn1OpenType(); 30 | type.Decode(buffer, false, 0); 31 | 32 | Value.Add(type); 33 | 34 | buffer.InvokeCharacters(type.ToString()); 35 | buffer.InvokeEndElement("...", -1); 36 | } 37 | 38 | public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging) 39 | { 40 | var num = 0; 41 | 42 | for (var i = Value.Count - 1; i >= 0; i--) 43 | { 44 | var type = (Asn1OpenType)Value[i]; 45 | num += type.Encode(buffer, false); 46 | } 47 | 48 | return num; 49 | } 50 | 51 | public override void Encode(Asn1BerOutputStream outs, bool explicitTagging) 52 | { 53 | foreach (Asn1OpenType type in Value) 54 | { 55 | if (type != null) 56 | { 57 | type.Encode(outs, false); 58 | } 59 | } 60 | } 61 | 62 | public override string ToString() 63 | { 64 | if (Value == null) 65 | { 66 | return ""; 67 | } 68 | 69 | var builder = new StringBuilder(); 70 | 71 | for (var i = 0; i < Value.Count; i++) 72 | { 73 | var type = (Asn1OpenType)Value[i]; 74 | 75 | if (i != 0) 76 | { 77 | builder.Append(", "); 78 | } 79 | 80 | builder.Append(type); 81 | } 82 | 83 | return builder.ToString(); 84 | } 85 | } 86 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Asn1/Gost/Gost_28147_89/Gost_28147_89_BlobParams.cs: -------------------------------------------------------------------------------- 1 | using GostCryptography.Asn1.Ber; 2 | using GostCryptography.Properties; 3 | 4 | namespace GostCryptography.Asn1.Gost.Gost_28147_89 5 | { 6 | public sealed class Gost_28147_89_BlobParams : Asn1Type 7 | { 8 | public Asn1ObjectIdentifier EncryptionParamSet { get; set; } 9 | 10 | public Asn1OpenExt ExtElement { get; set; } 11 | 12 | 13 | public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength) 14 | { 15 | var elemLength = explicitTagging ? MatchTag(buffer, Asn1Tag.Sequence) : implicitLength; 16 | 17 | EncryptionParamSet = null; 18 | ExtElement = null; 19 | 20 | var context = new Asn1BerDecodeContext(buffer, elemLength); 21 | var parsedLen = new IntHolder(); 22 | 23 | if (!context.MatchElemTag(0, 0, ObjectIdentifierTypeCode, parsedLen, false)) 24 | { 25 | throw ExceptionUtility.CryptographicException(Resources.Asn1MissingRequiredException, buffer.ByteCount); 26 | } 27 | 28 | EncryptionParamSet = new Asn1ObjectIdentifier(); 29 | EncryptionParamSet.Decode(buffer, true, parsedLen.Value); 30 | 31 | if (!context.Expired()) 32 | { 33 | if (buffer.PeekTag().Equals(0, 0, ObjectIdentifierTypeCode)) 34 | { 35 | throw ExceptionUtility.CryptographicException(Resources.Asn1SeqOrderException); 36 | } 37 | 38 | ExtElement = new Asn1OpenExt(); 39 | 40 | while (!context.Expired()) 41 | { 42 | ExtElement.DecodeComponent(buffer); 43 | } 44 | } 45 | else 46 | { 47 | ExtElement = null; 48 | } 49 | } 50 | 51 | public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging) 52 | { 53 | var len = 0; 54 | 55 | if (ExtElement != null) 56 | { 57 | len += ExtElement.Encode(buffer, false); 58 | } 59 | 60 | len += EncryptionParamSet.Encode(buffer, true); 61 | 62 | if (explicitTagging) 63 | { 64 | len += buffer.EncodeTagAndLength(Asn1Tag.Sequence, len); 65 | } 66 | 67 | return len; 68 | } 69 | } 70 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Gost_R3411/Gost_R3411_2012_256_PRF.cs: -------------------------------------------------------------------------------- 1 | using System.Security; 2 | 3 | using GostCryptography.Base; 4 | using GostCryptography.Gost_28147_89; 5 | 6 | namespace GostCryptography.Gost_R3411 7 | { 8 | /// 9 | /// Реализация PRF на базе алгоритма хэширования ГОСТ Р 34.11-2012/256. 10 | /// 11 | public sealed class Gost_R3411_2012_256_PRF : Gost_R3411_PRF 12 | { 13 | /// 14 | /// Наименование алгоритма PRF на базе ГОСТ Р 34.11-2012/256 для использования в протоколе WS-Trust. 15 | /// 16 | public const string WsTrustAlgorithmNameValue = "urn:ietf:params:xml:ns:cpxmlsec:algorithms:ck-p-gostr3411-2012-256"; 17 | 18 | /// 19 | /// Наименование алгоритма PRF на базе ГОСТ Р 34.11-2012/256 для использования в протоколах на базе WS-SecureConversation. 20 | /// 21 | public const string WsSecureConversationAlgorithmNameValue = "urn:ietf:params:xml:ns:cpxmlsec:algorithms:dk-p-gostr3411-2012-256"; 22 | 23 | /// 24 | /// Известные наименования алгоритма PRF на базе ГОСТ Р 34.11-2012/256. 25 | /// 26 | public static readonly string[] KnownAlgorithmNames = { WsTrustAlgorithmNameValue, WsSecureConversationAlgorithmNameValue }; 27 | 28 | 29 | /// 30 | [SecuritySafeCritical] 31 | public Gost_R3411_2012_256_PRF(Gost_28147_89_SymmetricAlgorithmBase key, byte[] label, byte[] seed) : base(key, label, seed) 32 | { 33 | } 34 | 35 | /// 36 | [SecuritySafeCritical] 37 | public Gost_R3411_2012_256_PRF(ProviderType providerType, byte[] key, byte[] label, byte[] seed) : base(providerType, key, label, seed) 38 | { 39 | } 40 | 41 | 42 | /// 43 | public override string AlgorithmName => WsTrustAlgorithmNameValue; 44 | 45 | 46 | /// 47 | [SecuritySafeCritical] 48 | protected override Gost_R3411_2012_256_HMAC CreateHMAC(Gost_28147_89_SymmetricAlgorithm key) 49 | { 50 | return new Gost_R3411_2012_256_HMAC(key); 51 | } 52 | } 53 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Gost_R3411/Gost_R3411_2012_512_PRF.cs: -------------------------------------------------------------------------------- 1 | using System.Security; 2 | 3 | using GostCryptography.Base; 4 | using GostCryptography.Gost_28147_89; 5 | 6 | namespace GostCryptography.Gost_R3411 7 | { 8 | /// 9 | /// Реализация PRF на базе алгоритма хэширования ГОСТ Р 34.11-2012/512. 10 | /// 11 | public sealed class Gost_R3411_2012_512_PRF : Gost_R3411_PRF 12 | { 13 | /// 14 | /// Наименование алгоритма PRF на базе ГОСТ Р 34.11-2012/512 для использования в протоколе WS-Trust. 15 | /// 16 | public const string WsTrustAlgorithmNameValue = "urn:ietf:params:xml:ns:cpxmlsec:algorithms:ck-p-gostr3411-2012-512"; 17 | 18 | /// 19 | /// Наименование алгоритма PRF на базе ГОСТ Р 34.11-2012/512 для использования в протоколах на базе WS-SecureConversation. 20 | /// 21 | public const string WsSecureConversationAlgorithmNameValue = "urn:ietf:params:xml:ns:cpxmlsec:algorithms:dk-p-gostr3411-2012-512"; 22 | 23 | /// 24 | /// Известные наименования алгоритма PRF на базе ГОСТ Р 34.11-2012/512. 25 | /// 26 | public static readonly string[] KnownAlgorithmNames = { WsTrustAlgorithmNameValue, WsSecureConversationAlgorithmNameValue }; 27 | 28 | 29 | /// 30 | [SecuritySafeCritical] 31 | public Gost_R3411_2012_512_PRF(Gost_28147_89_SymmetricAlgorithmBase key, byte[] label, byte[] seed) : base(key, label, seed) 32 | { 33 | } 34 | 35 | /// 36 | [SecuritySafeCritical] 37 | public Gost_R3411_2012_512_PRF(ProviderType providerType, byte[] key, byte[] label, byte[] seed) : base(providerType, key, label, seed) 38 | { 39 | } 40 | 41 | 42 | /// 43 | public override string AlgorithmName => WsTrustAlgorithmNameValue; 44 | 45 | 46 | /// 47 | [SecuritySafeCritical] 48 | protected override Gost_R3411_2012_512_HMAC CreateHMAC(Gost_28147_89_SymmetricAlgorithm key) 49 | { 50 | return new Gost_R3411_2012_512_HMAC(key); 51 | } 52 | } 53 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Asn1/Ber/Asn1BerDecodeContext.cs: -------------------------------------------------------------------------------- 1 | using GostCryptography.Properties; 2 | 3 | namespace GostCryptography.Asn1.Ber 4 | { 5 | public class Asn1BerDecodeContext 6 | { 7 | private readonly int _decBufByteCount; 8 | private readonly Asn1BerDecodeBuffer _decodeBuffer; 9 | private readonly int _elemLength; 10 | private readonly Asn1Tag _tagHolder; 11 | 12 | public Asn1BerDecodeContext(Asn1BerDecodeBuffer decodeBuffer, int elemLength) 13 | { 14 | _decodeBuffer = decodeBuffer; 15 | _decBufByteCount = decodeBuffer.ByteCount; 16 | _elemLength = elemLength; 17 | _tagHolder = new Asn1Tag(); 18 | } 19 | 20 | public virtual bool Expired() 21 | { 22 | if (_elemLength == Asn1Status.IndefiniteLength) 23 | { 24 | var parsedLen = new IntHolder(); 25 | var flag = _decodeBuffer.MatchTag(0, 0, 0, null, parsedLen); 26 | 27 | if (flag) 28 | { 29 | _decodeBuffer.Reset(); 30 | } 31 | 32 | return flag; 33 | } 34 | 35 | var num = _decodeBuffer.ByteCount - _decBufByteCount; 36 | 37 | return (num >= _elemLength); 38 | } 39 | 40 | public virtual bool MatchElemTag(Asn1Tag tag, IntHolder parsedLen, bool advance) 41 | { 42 | return MatchElemTag(tag.Class, tag.Form, tag.IdCode, parsedLen, advance); 43 | } 44 | 45 | public virtual bool MatchElemTag(short tagClass, short tagForm, int tagIdCode, IntHolder parsedLen, bool advance) 46 | { 47 | if (Expired()) 48 | { 49 | return false; 50 | } 51 | 52 | var flag = _decodeBuffer.MatchTag(tagClass, tagForm, tagIdCode, _tagHolder, parsedLen); 53 | 54 | if ((_elemLength != Asn1Status.IndefiniteLength) && (parsedLen.Value != Asn1Status.IndefiniteLength)) 55 | { 56 | var num = _decodeBuffer.ByteCount - _decBufByteCount; 57 | 58 | if ((parsedLen.Value < 0) || (parsedLen.Value > (_elemLength - num))) 59 | { 60 | throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidLengthException); 61 | } 62 | } 63 | 64 | if (flag && !advance) 65 | { 66 | _decodeBuffer.Reset(); 67 | } 68 | 69 | return flag; 70 | } 71 | } 72 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Gost_R3411/Gost_R3411_94_HashAlgorithm.cs: -------------------------------------------------------------------------------- 1 | using System.Security; 2 | 3 | using GostCryptography.Base; 4 | using GostCryptography.Native; 5 | 6 | namespace GostCryptography.Gost_R3411 7 | { 8 | /// 9 | /// Реализация алгоритма хэширования ГОСТ Р 34.11-94. 10 | /// 11 | public sealed class Gost_R3411_94_HashAlgorithm : Gost_R3411_HashAlgorithm 12 | { 13 | /// 14 | /// Размер хэша ГОСТ Р 34.11-94. 15 | /// 16 | public const int DefaultHashSizeValue = 256; 17 | 18 | /// 19 | /// Наименование алгоритма хэширования ГОСТ Р 34.11-94. 20 | /// 21 | public const string AlgorithmNameValue = "urn:ietf:params:xml:ns:cpxmlsec:algorithms:gostr3411"; 22 | 23 | /// 24 | /// Устаревшее наименование алгоритма хэширования ГОСТ Р 34.11-94. 25 | /// 26 | public const string ObsoleteAlgorithmNameValue = "http://www.w3.org/2001/04/xmldsig-more#gostr3411"; 27 | 28 | /// 29 | /// Известные наименования алгоритма хэширования ГОСТ Р 34.11-94. 30 | /// 31 | public static readonly string[] KnownAlgorithmNames = { AlgorithmNameValue, ObsoleteAlgorithmNameValue }; 32 | 33 | 34 | /// 35 | [SecuritySafeCritical] 36 | public Gost_R3411_94_HashAlgorithm() : base(DefaultHashSizeValue) 37 | { 38 | } 39 | 40 | /// 41 | [SecuritySafeCritical] 42 | public Gost_R3411_94_HashAlgorithm(ProviderType providerType) : base(providerType, DefaultHashSizeValue) 43 | { 44 | } 45 | 46 | [SecurityCritical] 47 | internal Gost_R3411_94_HashAlgorithm(ProviderType providerType, SafeProvHandleImpl providerHandle) : base(providerType, providerHandle, DefaultHashSizeValue) 48 | { 49 | } 50 | 51 | 52 | /// 53 | public override string AlgorithmName => AlgorithmNameValue; 54 | 55 | 56 | /// 57 | [SecurityCritical] 58 | protected override SafeHashHandleImpl CreateHashHandle(SafeProvHandleImpl providerHandle) 59 | { 60 | return CryptoApiHelper.CreateHash_3411_94(providerHandle); 61 | } 62 | } 63 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Asn1/Gost/Gost_28147_89/Gost_28147_89_KeyWrapParams.cs: -------------------------------------------------------------------------------- 1 | using GostCryptography.Asn1.Ber; 2 | using GostCryptography.Properties; 3 | 4 | namespace GostCryptography.Asn1.Gost.Gost_28147_89 5 | { 6 | public sealed class Gost_28147_89_KeyWrapParams : Asn1Type 7 | { 8 | public Asn1ObjectIdentifier EncryptionParamSet { get; set; } 9 | 10 | public Asn1OctetString Ukm { get; set; } 11 | 12 | 13 | public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength) 14 | { 15 | var elemLength = explicitTagging ? MatchTag(buffer, Asn1Tag.Sequence) : implicitLength; 16 | 17 | EncryptionParamSet = null; 18 | Ukm = null; 19 | 20 | var context = new Asn1BerDecodeContext(buffer, elemLength); 21 | var parsedLen = new IntHolder(); 22 | 23 | if (!context.MatchElemTag(0, 0, ObjectIdentifierTypeCode, parsedLen, false)) 24 | { 25 | throw ExceptionUtility.CryptographicException(Resources.Asn1MissingRequiredException, buffer.ByteCount); 26 | } 27 | 28 | EncryptionParamSet = new Asn1ObjectIdentifier(); 29 | EncryptionParamSet.Decode(buffer, true, parsedLen.Value); 30 | 31 | if (context.MatchElemTag(0, 0, OctetStringTypeCode, parsedLen, false)) 32 | { 33 | Ukm = new Asn1OctetString(); 34 | Ukm.Decode(buffer, true, parsedLen.Value); 35 | 36 | if (Ukm.Length != 8) 37 | { 38 | throw ExceptionUtility.CryptographicException(Resources.Asn1ConsVioException, nameof(Ukm.Length), Ukm.Length); 39 | } 40 | } 41 | } 42 | 43 | public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging) 44 | { 45 | var len = 0; 46 | 47 | if (Ukm != null) 48 | { 49 | if (Ukm.Length != 8) 50 | { 51 | throw ExceptionUtility.CryptographicException(Resources.Asn1ConsVioException, nameof(Ukm.Length), Ukm.Length); 52 | } 53 | 54 | len += Ukm.Encode(buffer, true); 55 | } 56 | 57 | len += EncryptionParamSet.Encode(buffer, true); 58 | 59 | if (explicitTagging) 60 | { 61 | len += buffer.EncodeTagAndLength(Asn1Tag.Sequence, len); 62 | } 63 | 64 | return len; 65 | } 66 | } 67 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Asn1/OidValue.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using System.Security.Cryptography; 3 | 4 | namespace GostCryptography.Asn1 5 | { 6 | public sealed class OidValue 7 | { 8 | public static readonly OidValue Null = new OidValue("", new int[] { }); 9 | 10 | 11 | private OidValue(string value, int[] items) 12 | { 13 | Value = value; 14 | Items = items; 15 | } 16 | 17 | 18 | public static OidValue FromString(string value) 19 | { 20 | var items = value.Split('.').Select(int.Parse).ToArray(); 21 | return new OidValue(value, items); 22 | } 23 | 24 | public static OidValue FromArray(int[] items) 25 | { 26 | string value = string.Join(".", items); 27 | return new OidValue(value, items); 28 | } 29 | 30 | 31 | public string Value { get; } 32 | 33 | public int[] Items { get; } 34 | 35 | 36 | public override int GetHashCode() 37 | { 38 | if (Items == null) 39 | { 40 | return 0; 41 | } 42 | 43 | var result = 1; 44 | 45 | foreach (var item in Items) 46 | { 47 | result = 31 * result + item.GetHashCode(); 48 | } 49 | 50 | return result; 51 | } 52 | 53 | public override bool Equals(object obj) 54 | { 55 | if (this == obj) 56 | { 57 | return true; 58 | } 59 | 60 | if (!(obj is OidValue)) 61 | { 62 | return false; 63 | } 64 | 65 | var other = (OidValue)obj; 66 | 67 | if (Items == other.Items) 68 | { 69 | return true; 70 | } 71 | 72 | if (Items == null || other.Items == null) 73 | { 74 | return false; 75 | } 76 | 77 | if (Items.Length != other.Items.Length) 78 | { 79 | return false; 80 | } 81 | 82 | for (var i = 0; i < Items.Length; ++i) 83 | { 84 | if (Items[i] != other.Items[i]) 85 | { 86 | return false; 87 | } 88 | } 89 | 90 | return true; 91 | } 92 | 93 | public override string ToString() 94 | { 95 | return Value; 96 | } 97 | 98 | 99 | public Oid ToOid() 100 | { 101 | return new Oid(Value); 102 | } 103 | } 104 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Base/GostSignatureFormatter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Security.Cryptography; 3 | 4 | using GostCryptography.Properties; 5 | 6 | namespace GostCryptography.Base 7 | { 8 | /// 9 | /// Класс вычисления цифровой подписи ГОСТ. 10 | /// 11 | public class GostSignatureFormatter : AsymmetricSignatureFormatter 12 | { 13 | /// 14 | /// Конструктор. 15 | /// 16 | public GostSignatureFormatter() 17 | { 18 | } 19 | 20 | /// 21 | /// Конструктор. 22 | /// 23 | /// Закрытый ключ для вычисления цифровой подписи. 24 | /// 25 | /// 26 | public GostSignatureFormatter(AsymmetricAlgorithm privateKey) : this() 27 | { 28 | SetKey(privateKey); 29 | } 30 | 31 | 32 | private GostAsymmetricAlgorithm _privateKey; 33 | 34 | 35 | /// 36 | public override void SetKey(AsymmetricAlgorithm privateKey) 37 | { 38 | if (privateKey == null) 39 | { 40 | throw ExceptionUtility.ArgumentNull(nameof(privateKey)); 41 | } 42 | 43 | if (!(privateKey is GostAsymmetricAlgorithm gostPrivateKey)) 44 | { 45 | if (privateKey.SignatureAlgorithm.IndexOf("gost", StringComparison.OrdinalIgnoreCase) < 0) 46 | { 47 | throw ExceptionUtility.ArgumentOutOfRange(nameof(privateKey), Resources.ShouldSupportGost3410); 48 | } 49 | 50 | gostPrivateKey = new GostExternalAsymmetricAlgorithm(privateKey); 51 | } 52 | 53 | _privateKey = gostPrivateKey; 54 | } 55 | 56 | /// 57 | public override void SetHashAlgorithm(string hashAlgorithmName) 58 | { 59 | } 60 | 61 | /// 62 | public override byte[] CreateSignature(byte[] hash) 63 | { 64 | if (hash == null) 65 | { 66 | throw ExceptionUtility.ArgumentNull(nameof(hash)); 67 | } 68 | 69 | var reverseSignature = _privateKey.CreateSignature(hash); 70 | Array.Reverse(reverseSignature); 71 | 72 | return reverseSignature; 73 | } 74 | } 75 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Asn1/Ber/Asn1EncodeBuffer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | 4 | namespace GostCryptography.Asn1.Ber 5 | { 6 | public abstract class Asn1EncodeBuffer : Asn1MessageBuffer 7 | { 8 | public const int DefaultSizeIncrement = 0x400; 9 | 10 | protected byte[] Data; 11 | protected int ByteIndex; 12 | protected int SizeIncrement; 13 | 14 | protected Asn1EncodeBuffer() 15 | { 16 | InitBuffer(DefaultSizeIncrement); 17 | } 18 | 19 | protected Asn1EncodeBuffer(int sizeIncrement) 20 | { 21 | if (sizeIncrement == 0) 22 | { 23 | sizeIncrement = DefaultSizeIncrement; 24 | } 25 | 26 | InitBuffer(sizeIncrement); 27 | } 28 | 29 | public abstract byte[] MsgCopy { get; } 30 | 31 | public abstract int MsgLength { get; } 32 | 33 | public virtual void BinDump(string varName) 34 | { 35 | var outs = new StreamWriter(Console.OpenStandardOutput(), Console.Out.Encoding) 36 | { 37 | AutoFlush = true 38 | }; 39 | 40 | BinDump(outs, varName); 41 | } 42 | 43 | public abstract void BinDump(StreamWriter outs, string varName); 44 | 45 | protected internal virtual void CheckSize(int bytesRequired) 46 | { 47 | if ((ByteIndex + bytesRequired) > Data.Length) 48 | { 49 | var num = ((bytesRequired - 1) / SizeIncrement) + 1; 50 | var num2 = num * SizeIncrement; 51 | var destinationArray = new byte[Data.Length + num2]; 52 | 53 | Array.Copy(Data, 0, destinationArray, 0, ByteIndex + 1); 54 | 55 | Data = destinationArray; 56 | } 57 | } 58 | 59 | public abstract void Copy(byte value); 60 | 61 | public abstract void Copy(byte[] value); 62 | 63 | public virtual void HexDump() 64 | { 65 | HexDump(GetInputStream()); 66 | } 67 | 68 | public virtual void HexDump(StreamWriter outs) 69 | { 70 | HexDump(GetInputStream(), outs); 71 | } 72 | 73 | protected virtual void InitBuffer(int sizeIncrement) 74 | { 75 | SizeIncrement = sizeIncrement; 76 | Data = new byte[SizeIncrement]; 77 | ByteIndex = 0; 78 | } 79 | 80 | public abstract void Reset(); 81 | 82 | public abstract void Write(Stream outs); 83 | } 84 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Asn1/Ber/Asn1Integer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace GostCryptography.Asn1.Ber 4 | { 5 | [Serializable] 6 | public class Asn1Integer : Asn1Type 7 | { 8 | public const int SizeOfInt = 4; 9 | public const int SizeOfLong = 8; 10 | public static readonly Asn1Tag Tag = new Asn1Tag(0, 0, BigIntegerTypeCode); 11 | 12 | [NonSerialized] 13 | public long Value; 14 | 15 | public Asn1Integer() 16 | { 17 | Value = 0L; 18 | } 19 | 20 | public Asn1Integer(long value) 21 | { 22 | Value = value; 23 | } 24 | 25 | public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength) 26 | { 27 | var length = explicitTagging ? MatchTag(buffer, Tag) : implicitLength; 28 | Value = Asn1RunTime.DecodeIntValue(buffer, length, true); 29 | buffer.TypeCode = BigIntegerTypeCode; 30 | } 31 | 32 | public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging) 33 | { 34 | var len = buffer.EncodeIntValue(Value); 35 | 36 | if (explicitTagging) 37 | { 38 | len += buffer.EncodeTagAndLength(Tag, len); 39 | } 40 | 41 | return len; 42 | } 43 | 44 | public override void Encode(Asn1BerOutputStream outs, bool explicitTagging) 45 | { 46 | if (explicitTagging) 47 | { 48 | outs.EncodeTag(Tag); 49 | } 50 | 51 | outs.EncodeIntValue(Value, true); 52 | } 53 | 54 | public virtual bool Equals(long value) 55 | { 56 | return (Value == value); 57 | } 58 | 59 | public override bool Equals(object value) 60 | { 61 | var integer = value as Asn1Integer; 62 | 63 | if (integer == null) 64 | { 65 | return false; 66 | } 67 | 68 | return (Value == integer.Value); 69 | } 70 | 71 | public virtual int GetBitCount() 72 | { 73 | return Asn1RunTime.GetLongBitCount(Value); 74 | } 75 | 76 | public static int GetBitCount(long ivalue) 77 | { 78 | return Asn1RunTime.GetLongBitCount(ivalue); 79 | } 80 | 81 | public override int GetHashCode() 82 | { 83 | return Value.GetHashCode(); 84 | } 85 | 86 | public override string ToString() 87 | { 88 | return Convert.ToString(Value); 89 | } 90 | } 91 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Gost_R3411/Gost_R3411_94_HMAC.cs: -------------------------------------------------------------------------------- 1 | using System.Security; 2 | 3 | using GostCryptography.Base; 4 | using GostCryptography.Gost_28147_89; 5 | using GostCryptography.Native; 6 | 7 | namespace GostCryptography.Gost_R3411 8 | { 9 | /// 10 | /// Реализация HMAC на базе алгоритма хэширования ГОСТ Р 34.11-94. 11 | /// 12 | public sealed class Gost_R3411_94_HMAC : Gost_R3411_HMAC 13 | { 14 | /// 15 | /// Наименование алгоритма HMAC на базе ГОСТ Р 34.11-94. 16 | /// 17 | public const string AlgorithmNameValue = "urn:ietf:params:xml:ns:cpxmlsec:algorithms:hmac-gostr3411"; 18 | 19 | /// 20 | /// Устаревшее наименование алгоритма HMAC на базе ГОСТ Р 34.11-94. 21 | /// 22 | public const string ObsoleteAlgorithmNameValue = "http://www.w3.org/2001/04/xmldsig-more#hmac-gostr3411"; 23 | 24 | /// 25 | /// Известные наименования алгоритма HMAC на базе ГОСТ Р 34.11-94. 26 | /// 27 | public static readonly string[] KnownAlgorithmNames = { AlgorithmNameValue, ObsoleteAlgorithmNameValue }; 28 | 29 | 30 | /// 31 | [SecuritySafeCritical] 32 | public Gost_R3411_94_HMAC() : base(Gost_R3411_94_HashAlgorithm.DefaultHashSizeValue) 33 | { 34 | } 35 | 36 | /// 37 | [SecuritySafeCritical] 38 | public Gost_R3411_94_HMAC(ProviderType providerType) : base(providerType, Gost_R3411_94_HashAlgorithm.DefaultHashSizeValue) 39 | { 40 | } 41 | 42 | /// 43 | [SecuritySafeCritical] 44 | public Gost_R3411_94_HMAC(Gost_28147_89_SymmetricAlgorithmBase keyAlgorithm) : base(keyAlgorithm, Gost_R3411_94_HashAlgorithm.DefaultHashSizeValue) 45 | { 46 | } 47 | 48 | 49 | /// 50 | public override string AlgorithmName => AlgorithmNameValue; 51 | 52 | 53 | /// 54 | [SecuritySafeCritical] 55 | protected override SafeHashHandleImpl CreateHashHMAC(ProviderType providerType, SafeProvHandleImpl providerHandle, SafeKeyHandleImpl symKeyHandle) 56 | { 57 | return CryptoApiHelper.CreateHashHMAC_94(providerType, providerHandle, symKeyHandle); 58 | } 59 | } 60 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Base/GostSignatureDeformatter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Security.Cryptography; 3 | 4 | using GostCryptography.Properties; 5 | 6 | namespace GostCryptography.Base 7 | { 8 | /// 9 | /// Класс проверки цифровой подписи ГОСТ. 10 | /// 11 | public class GostSignatureDeformatter : AsymmetricSignatureDeformatter 12 | { 13 | /// 14 | /// Конструктор. 15 | /// 16 | public GostSignatureDeformatter() 17 | { 18 | } 19 | 20 | /// 21 | /// Конструктор. 22 | /// 23 | /// Открытый ключ для проверки цифровой подписи. 24 | /// 25 | /// 26 | public GostSignatureDeformatter(AsymmetricAlgorithm publicKey) : this() 27 | { 28 | SetKey(publicKey); 29 | } 30 | 31 | 32 | private GostAsymmetricAlgorithm _publicKey; 33 | 34 | 35 | /// 36 | public override void SetKey(AsymmetricAlgorithm publicKey) 37 | { 38 | if (publicKey == null) 39 | { 40 | throw ExceptionUtility.ArgumentNull(nameof(publicKey)); 41 | } 42 | 43 | if (!(publicKey is GostAsymmetricAlgorithm gostPublicKey)) 44 | { 45 | if (publicKey.SignatureAlgorithm.IndexOf("gost", StringComparison.OrdinalIgnoreCase) < 0) 46 | { 47 | throw ExceptionUtility.ArgumentOutOfRange(nameof(publicKey), Resources.ShouldSupportGost3410); 48 | } 49 | 50 | gostPublicKey = new GostExternalAsymmetricAlgorithm(publicKey); 51 | } 52 | 53 | _publicKey = gostPublicKey; 54 | } 55 | 56 | /// 57 | public override void SetHashAlgorithm(string hashAlgorithmName) 58 | { 59 | } 60 | 61 | /// 62 | public override bool VerifySignature(byte[] hash, byte[] signature) 63 | { 64 | if (hash == null) 65 | { 66 | throw ExceptionUtility.ArgumentNull(nameof(hash)); 67 | } 68 | 69 | if (signature == null) 70 | { 71 | throw ExceptionUtility.ArgumentNull(nameof(signature)); 72 | } 73 | 74 | var reverseSignature = (byte[])signature.Clone(); 75 | Array.Reverse(reverseSignature); 76 | 77 | return _publicKey.VerifySignature(hash, reverseSignature); 78 | } 79 | } 80 | } -------------------------------------------------------------------------------- /Source/GostCryptography/GostCryptography.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netstandard2.0;net6.0 5 | true 6 | GostCryptography 7 | IT.GostCryptography 8 | 6.0.0.1 9 | 6.0.0.1 10 | true 11 | 12 | 13 | 14 | 1701;1702;1591 15 | IT.GostCryptography 16 | GostCryptography 17 | 6.0.0.1 18 | Alexander Mezhov, Ivan Tikhonov 19 | 20 | .NET 6.0 driver for ViPNet CSP and CryptoPro CSP (Linux & Windows). 21 | Migrated https://www.nuget.org/packages/GostCryptography to .NET 6 22 | MIT 23 | https://github.com/pairbit/IT.GostCryptography 24 | 25 | GOST GOST-2012 Cryptography ViPNet CryptoPro 26 | git 27 | https://github.com/pairbit/IT.GostCryptography 28 | true 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | True 40 | True 41 | Resources.resx 42 | 43 | 44 | 45 | 46 | 47 | ResXFileCodeGenerator 48 | Resources.Designer.cs 49 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /Source/GostCryptography.Tests/Pkcs/EnvelopedCmsEncryptTest.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using System.Security.Cryptography.Pkcs; 3 | using System.Security.Cryptography.X509Certificates; 4 | using System.Text; 5 | 6 | using NUnit.Framework; 7 | 8 | namespace GostCryptography.Tests.Pkcs 9 | { 10 | /// 11 | /// Шифрация и дешифрация сообщения CMS/PKCS#7. 12 | /// 13 | /// 14 | /// Тест создает сообщение, шифрует его в формате CMS/PKCS#7, а затем дешифрует зашифрованное сообщение. 15 | /// 16 | [TestFixture(Description = "Шифрация и дешифрация сообщения CMS/PKCS#7")] 17 | public class EnvelopedCmsEncryptTest 18 | { 19 | [Test] 20 | [TestCaseSource(typeof(TestConfig), nameof(TestConfig.Gost_R3410_Certificates))] 21 | public void ShouldEncryptAndDecrypt(TestCertificateInfo testCase) 22 | { 23 | // Given 24 | var certificate = testCase.Certificate; 25 | var message = CreateMessage(); 26 | 27 | // When 28 | var encryptedMessage = EncryptMessage(certificate, message); 29 | var decryptedMessage = DecryptMessage(encryptedMessage); 30 | 31 | // Then 32 | Assert.IsTrue(message.SequenceEqual(decryptedMessage)); 33 | } 34 | 35 | private static byte[] CreateMessage() 36 | { 37 | // Некоторое сообщение для подписи 38 | 39 | return Encoding.UTF8.GetBytes("Some message to sign..."); 40 | } 41 | 42 | private static byte[] EncryptMessage(X509Certificate2 certificate, byte[] message) 43 | { 44 | // Создание объекта для шифрования сообщения 45 | var envelopedCms = new EnvelopedCms(new ContentInfo(message)); 46 | 47 | // Создание объект с информацией о получателе 48 | var recipient = new CmsRecipient(SubjectIdentifierType.IssuerAndSerialNumber, certificate); 49 | 50 | // Шифрование сообщения CMS/PKCS#7 51 | envelopedCms.Encrypt(recipient); 52 | 53 | // Создание сообщения CMS/PKCS#7 54 | return envelopedCms.Encode(); 55 | } 56 | 57 | private static byte[] DecryptMessage(byte[] encryptedMessage) 58 | { 59 | // Создание объекта для расшифровки сообщения 60 | var envelopedCms = new EnvelopedCms(); 61 | 62 | // Чтение сообщения CMS/PKCS#7 63 | envelopedCms.Decode(encryptedMessage); 64 | 65 | // Расшифровка сообщения CMS/PKCS#7 66 | envelopedCms.Decrypt(envelopedCms.RecipientInfos[0]); 67 | 68 | return envelopedCms.ContentInfo.Content; 69 | } 70 | } 71 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Asn1/Ber/Asn1Boolean.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | using GostCryptography.Properties; 4 | 5 | namespace GostCryptography.Asn1.Ber 6 | { 7 | [Serializable] 8 | public class Asn1Boolean : Asn1Type 9 | { 10 | public static readonly Asn1Tag Tag = new Asn1Tag(0, 0, BooleanTypeCode); 11 | public static readonly Asn1Boolean FalseValue = new Asn1Boolean(false); 12 | public static readonly Asn1Boolean TrueValue = new Asn1Boolean(true); 13 | 14 | [NonSerialized] 15 | public bool Value; 16 | 17 | public Asn1Boolean() 18 | { 19 | Value = false; 20 | } 21 | 22 | public Asn1Boolean(bool value) 23 | { 24 | Value = value; 25 | } 26 | 27 | public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength) 28 | { 29 | if (explicitTagging) 30 | { 31 | MatchTag(buffer, Tag); 32 | } 33 | 34 | var num = buffer.Read(); 35 | 36 | if (num < 0) 37 | { 38 | throw ExceptionUtility.CryptographicException(Resources.Asn1EndOfBufferException, buffer.ByteCount); 39 | } 40 | 41 | buffer.TypeCode = BooleanTypeCode; 42 | Value = num != 0; 43 | } 44 | 45 | public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging) 46 | { 47 | var len = 1; 48 | 49 | buffer.Copy(Value ? byte.MaxValue : ((byte)0)); 50 | 51 | if (explicitTagging) 52 | { 53 | len += buffer.EncodeTagAndLength(Tag, len); 54 | } 55 | 56 | return len; 57 | } 58 | 59 | public override void Encode(Asn1BerOutputStream outs, bool explicitTagging) 60 | { 61 | if (explicitTagging) 62 | { 63 | outs.EncodeTag(Tag); 64 | } 65 | 66 | outs.EncodeLength(1); 67 | outs.WriteByte(Value ? -1 : 0); 68 | } 69 | 70 | public virtual bool Equals(bool value) 71 | { 72 | return (Value == value); 73 | } 74 | 75 | public override bool Equals(object value) 76 | { 77 | var flag = value as Asn1Boolean; 78 | 79 | if (flag == null) 80 | { 81 | return false; 82 | } 83 | 84 | return (Value == flag.Value); 85 | } 86 | 87 | public override int GetHashCode() 88 | { 89 | return Value.GetHashCode(); 90 | } 91 | 92 | public override string ToString() 93 | { 94 | if (!Value) 95 | { 96 | return "FALSE"; 97 | } 98 | 99 | return "TRUE"; 100 | } 101 | } 102 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Asn1/Ber/Asn1OpenType.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Text; 4 | 5 | namespace GostCryptography.Asn1.Ber 6 | { 7 | [Serializable] 8 | public class Asn1OpenType : Asn1OctetString 9 | { 10 | private const string EncodedDataMessage = "ENCODED DATA"; 11 | 12 | [NonSerialized] 13 | private readonly Asn1EncodeBuffer _encodeBuffer; 14 | 15 | [NonSerialized] 16 | private readonly int _length; 17 | 18 | [NonSerialized] 19 | private readonly bool _textEncoding; 20 | 21 | 22 | public Asn1OpenType() 23 | { 24 | _length = 0; 25 | _textEncoding = false; 26 | } 27 | 28 | public Asn1OpenType(byte[] data) 29 | : base(data) 30 | { 31 | _length = 0; 32 | _textEncoding = false; 33 | } 34 | 35 | public Asn1OpenType(Asn1EncodeBuffer buffer) 36 | { 37 | if (buffer is Asn1BerEncodeBuffer) 38 | { 39 | _length = buffer.MsgLength; 40 | _encodeBuffer = buffer; 41 | } 42 | else 43 | { 44 | Value = buffer.MsgCopy; 45 | } 46 | 47 | _textEncoding = false; 48 | } 49 | 50 | public Asn1OpenType(byte[] data, int offset, int nbytes) 51 | : base(data, offset, nbytes) 52 | { 53 | _length = 0; 54 | _textEncoding = false; 55 | } 56 | 57 | public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength) 58 | { 59 | Value = buffer.DecodeOpenType(); 60 | buffer.TypeCode = OpenTypeTypeCode; 61 | } 62 | 63 | public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging) 64 | { 65 | if (Value == null) 66 | { 67 | return _length; 68 | } 69 | 70 | return base.Encode(buffer, false); 71 | } 72 | 73 | public override void Encode(Asn1BerOutputStream outs, bool explicitTagging) 74 | { 75 | if (Value != null) 76 | { 77 | outs.Write(Value); 78 | } 79 | } 80 | 81 | public override string ToString() 82 | { 83 | if (Value != null) 84 | { 85 | try 86 | { 87 | return (_textEncoding ? Encoding.UTF8.GetString(Value, 0, Value.Length) : base.ToString()); 88 | } 89 | catch (IOException) 90 | { 91 | return null; 92 | } 93 | } 94 | 95 | if (_encodeBuffer != null) 96 | { 97 | return _encodeBuffer.ToString(); 98 | } 99 | 100 | return EncodedDataMessage; 101 | } 102 | } 103 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Gost_28147_89/Gost_28147_89_SymmetricAlgorithmBase.cs: -------------------------------------------------------------------------------- 1 | using System.Security.Cryptography; 2 | 3 | using GostCryptography.Base; 4 | 5 | namespace GostCryptography.Gost_28147_89 6 | { 7 | /// 8 | /// Базовый класс для всех реализаций симметричного шифрования по ГОСТ 28147-89. 9 | /// 10 | public abstract class Gost_28147_89_SymmetricAlgorithmBase : GostSymmetricAlgorithm 11 | { 12 | public const int DefaultIvSize = 8; 13 | public const int DefaultKeySize = 256; 14 | public const int DefaultBlockSize = 64; 15 | public const int DefaultFeedbackSize = 64; 16 | public static readonly KeySizes[] DefaultLegalKeySizes = { new KeySizes(DefaultKeySize, DefaultKeySize, 0) }; 17 | public static readonly KeySizes[] DefaultLegalBlockSizes = { new KeySizes(DefaultBlockSize, DefaultBlockSize, 0) }; 18 | 19 | 20 | /// 21 | protected Gost_28147_89_SymmetricAlgorithmBase() 22 | { 23 | InitDefaults(); 24 | } 25 | 26 | /// 27 | protected Gost_28147_89_SymmetricAlgorithmBase(ProviderType providerType) : base(providerType) 28 | { 29 | InitDefaults(); 30 | } 31 | 32 | 33 | private void InitDefaults() 34 | { 35 | KeySizeValue = DefaultKeySize; 36 | BlockSizeValue = DefaultBlockSize; 37 | FeedbackSizeValue = DefaultFeedbackSize; 38 | LegalBlockSizesValue = DefaultLegalBlockSizes; 39 | LegalKeySizesValue = DefaultLegalKeySizes; 40 | } 41 | 42 | 43 | /// 44 | /// Хэширует секретный ключ. 45 | /// 46 | public abstract byte[] ComputeHash(HashAlgorithm hash); 47 | 48 | /// 49 | /// Экспортирует (шифрует) секретный ключ. 50 | /// 51 | /// Общий секретный ключ. 52 | /// Алгоритм экспорта общего секретного ключа. 53 | public abstract byte[] EncodePrivateKey(Gost_28147_89_SymmetricAlgorithmBase keyExchangeAlgorithm, GostKeyExchangeExportMethod keyExchangeExportMethod); 54 | 55 | /// 56 | /// Импортирует (дешифрует) секретный ключ. 57 | /// 58 | /// Зашифрованный общий секретный ключ. 59 | /// Алгоритм экспорта общего секретного ключа. 60 | public abstract SymmetricAlgorithm DecodePrivateKey(byte[] encodedKeyExchangeData, GostKeyExchangeExportMethod keyExchangeExportMethod); 61 | } 62 | } -------------------------------------------------------------------------------- /Source/GostCryptography.Tests/Sign/SignDataStreamCertificateTest.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | using System.Security.Cryptography.X509Certificates; 3 | using System.Text; 4 | 5 | using GostCryptography.Base; 6 | 7 | using NUnit.Framework; 8 | 9 | namespace GostCryptography.Tests.Sign 10 | { 11 | /// 12 | /// Подпись и проверка подписи потока байт с помощью сертификата. 13 | /// 14 | /// 15 | /// Тест создает поток байт, вычисляет цифровую подпись потока байт с использованием закрытого ключа сертификата, 16 | /// а затем с помощью открытого ключа сертификата проверяет полученную подпись. 17 | /// 18 | [TestFixture(Description = "Подпись и проверка подписи потока байт с помощью сертификата")] 19 | public class SignDataStreamCertificateTest 20 | { 21 | [Test] 22 | [TestCaseSource(typeof(TestConfig), nameof(TestConfig.Gost_R3410_Certificates))] 23 | public void ShouldSignDataStream(TestCertificateInfo testCase) 24 | { 25 | // Given 26 | var certificate = testCase.Certificate; 27 | var privateKey = (GostAsymmetricAlgorithm)certificate.GetPrivateKeyAlgorithm(); 28 | var publicKey = (GostAsymmetricAlgorithm)certificate.GetPublicKeyAlgorithm(); 29 | var dataStream = CreateDataStream(); 30 | 31 | // When 32 | 33 | dataStream.Seek(0, SeekOrigin.Begin); 34 | var signature = CreateSignature(privateKey, dataStream); 35 | 36 | dataStream.Seek(0, SeekOrigin.Begin); 37 | var isValidSignature = VerifySignature(publicKey, dataStream, signature); 38 | 39 | // Then 40 | Assert.IsTrue(isValidSignature); 41 | } 42 | 43 | private static Stream CreateDataStream() 44 | { 45 | // Некоторый поток байт для подписи 46 | 47 | return new MemoryStream(Encoding.UTF8.GetBytes("Some data to sign...")); 48 | } 49 | 50 | private static byte[] CreateSignature(GostAsymmetricAlgorithm privateKey, Stream dataStream) 51 | { 52 | byte[] hash; 53 | 54 | using (var hashAlg = privateKey.CreateHashAlgorithm()) 55 | { 56 | hash = hashAlg.ComputeHash(dataStream); 57 | } 58 | 59 | return privateKey.CreateSignature(hash); 60 | } 61 | 62 | private static bool VerifySignature(GostAsymmetricAlgorithm publicKey, Stream dataStream, byte[] signature) 63 | { 64 | byte[] hash; 65 | 66 | using (var hashAlg = publicKey.CreateHashAlgorithm()) 67 | { 68 | hash = hashAlg.ComputeHash(dataStream); 69 | } 70 | 71 | return publicKey.VerifySignature(hash, signature); 72 | } 73 | } 74 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Base/ProviderType.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace GostCryptography.Base 4 | { 5 | /// 6 | /// Типы криптографических провайдеров. 7 | /// 8 | public enum ProviderType 9 | { 10 | /// 11 | /// Infotecs Cryptographic Service Provider. 12 | /// 13 | VipNet = 2, 14 | 15 | /// 16 | /// Infotecs GOST 2012/512 Cryptographic Service Provider. 17 | /// 18 | VipNet_2012_512 = 77, 19 | 20 | /// 21 | /// Infotecs GOST 2012/1024 Cryptographic Service Provider. 22 | /// 23 | VipNet_2012_1024 = 78, 24 | 25 | 26 | /// 27 | /// Crypto-Pro GOST R 34.10-2001 Cryptographic Service Provider. 28 | /// 29 | CryptoPro = 75, 30 | 31 | /// 32 | /// Crypto-Pro GOST R 34.10-2012 Cryptographic Service Provider. 33 | /// 34 | CryptoPro_2012_512 = 80, 35 | 36 | /// 37 | /// Crypto-Pro GOST R 34.10-2012 Strong Cryptographic Service Provider. 38 | /// 39 | CryptoPro_2012_1024 = 81 40 | } 41 | 42 | 43 | /// 44 | /// Методы расширения . 45 | /// 46 | public static class ProviderTypesExtensions 47 | { 48 | /// 49 | /// Набор провайдеров VipNet. 50 | /// 51 | public static readonly HashSet VipNetProviders = new HashSet 52 | { 53 | ProviderType.VipNet, 54 | ProviderType.VipNet_2012_512, 55 | ProviderType.VipNet_2012_1024 56 | }; 57 | 58 | /// 59 | /// Набор провайдеров CryptoPro. 60 | /// 61 | public static readonly HashSet CryptoProProviders = new HashSet 62 | { 63 | ProviderType.CryptoPro, 64 | ProviderType.CryptoPro_2012_512, 65 | ProviderType.CryptoPro_2012_1024 66 | }; 67 | 68 | 69 | /// 70 | /// Возвращает для VipNet. 71 | /// 72 | public static bool IsVipNet(this ProviderType providerType) => VipNetProviders.Contains(providerType); 73 | 74 | /// 75 | /// Возвращает для CryptoPro. 76 | /// 77 | public static bool IsCryptoPro(this ProviderType providerType) => CryptoProProviders.Contains(providerType); 78 | 79 | 80 | /// 81 | /// Преобразует значение в . 82 | /// 83 | public static int ToInt(this ProviderType providerType) => (int)providerType; 84 | } 85 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Base/GostKeyExchangeAlgorithm.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Security; 3 | using System.Security.Cryptography; 4 | 5 | using GostCryptography.Config; 6 | 7 | namespace GostCryptography.Base 8 | { 9 | /// 10 | /// Базовый класс всех реализаций общего секретного ключа ГОСТ. 11 | /// 12 | public abstract class GostKeyExchangeAlgorithm : IDisposable, IGostAlgorithm 13 | { 14 | /// 15 | /// Конструктор. 16 | /// 17 | /// 18 | /// По умолчанию использует криптографический провайдер, установленный в . 19 | /// 20 | [SecuritySafeCritical] 21 | protected GostKeyExchangeAlgorithm() : this(GostCryptoConfig.ProviderType) 22 | { 23 | } 24 | 25 | /// 26 | /// Конструктор. 27 | /// 28 | /// Тип криптографического провайдера. 29 | [SecuritySafeCritical] 30 | protected GostKeyExchangeAlgorithm(ProviderType providerType) 31 | { 32 | ProviderType = providerType; 33 | } 34 | 35 | 36 | /// 37 | public ProviderType ProviderType { get; } 38 | 39 | /// 40 | public virtual string AlgorithmName => GetType().Name; 41 | 42 | 43 | /// 44 | /// Экспортирует (шифрует) общий секретный ключ. 45 | /// 46 | /// Общий секретный ключ. 47 | /// Алгоритм экспорта общего секретного ключа. 48 | public abstract byte[] EncodeKeyExchange(SymmetricAlgorithm keyExchangeAlgorithm, GostKeyExchangeExportMethod keyExchangeExportMethod); 49 | 50 | /// 51 | /// Импортирует (дешифрует) общий секретный ключ. 52 | /// 53 | /// Общий секретный ключ. 54 | /// Алгоритм экспорта общего секретного ключа. 55 | public abstract SymmetricAlgorithm DecodeKeyExchange(byte[] encodedKeyExchangeData, GostKeyExchangeExportMethod keyExchangeExportMethod); 56 | 57 | 58 | /// 59 | /// Освобождает неуправляемые ресурсы. 60 | /// 61 | protected virtual void Dispose(bool disposing) 62 | { 63 | } 64 | 65 | /// 66 | public void Dispose() 67 | { 68 | Dispose(true); 69 | GC.SuppressFinalize(this); 70 | } 71 | 72 | /// 73 | ~GostKeyExchangeAlgorithm() 74 | { 75 | Dispose(false); 76 | } 77 | } 78 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Asn1/Ber/Asn1Utf8String.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Text; 4 | 5 | namespace GostCryptography.Asn1.Ber 6 | { 7 | [Serializable] 8 | public class Asn1Utf8String : Asn1CharString 9 | { 10 | public static readonly Asn1Tag Tag = new Asn1Tag(0, 0, Utf8StringTypeCode); 11 | 12 | public Asn1Utf8String() 13 | : base(Utf8StringTypeCode) 14 | { 15 | } 16 | 17 | public Asn1Utf8String(string data) 18 | : base(data, Utf8StringTypeCode) 19 | { 20 | } 21 | 22 | private byte[] AllocByteArray(int nbytes) 23 | { 24 | return new byte[nbytes]; 25 | } 26 | 27 | public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength) 28 | { 29 | var num = explicitTagging ? MatchTag(buffer, Tag) : implicitLength; 30 | var str = new Asn1OctetString(); 31 | str.Decode(buffer, false, num); 32 | 33 | Value = Encoding.UTF8.GetString(str.Value, 0, str.Value.Length); 34 | 35 | if (explicitTagging && (num == Asn1Status.IndefiniteLength)) 36 | { 37 | MatchTag(buffer, Asn1Tag.Eoc); 38 | } 39 | } 40 | 41 | public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging) 42 | { 43 | var len = 0; 44 | 45 | try 46 | { 47 | var bytes = Encoding.UTF8.GetBytes(Value); 48 | len = bytes.Length; 49 | buffer.Copy(bytes); 50 | } 51 | catch (IOException exception) 52 | { 53 | Console.Out.WriteLine("This JVM does not support UTF-8 encoding"); 54 | Asn1Util.WriteStackTrace(exception, Console.Error); 55 | } 56 | 57 | if (explicitTagging) 58 | { 59 | len += buffer.EncodeTagAndLength(Tag, len); 60 | } 61 | 62 | return len; 63 | } 64 | 65 | public override void Encode(Asn1BerOutputStream outs, bool explicitTagging) 66 | { 67 | try 68 | { 69 | var bytes = Encoding.UTF8.GetBytes(Value); 70 | 71 | if (explicitTagging) 72 | { 73 | outs.EncodeTag(Tag); 74 | } 75 | 76 | outs.EncodeLength(bytes.Length); 77 | outs.Write(bytes); 78 | } 79 | catch (IOException exception) 80 | { 81 | Console.Out.WriteLine("This JVM does not support UTF-8 encoding"); 82 | Asn1Util.WriteStackTrace(exception, Console.Error); 83 | } 84 | } 85 | 86 | private byte[] ReAllocByteArray(byte[] ba1, int nbytes) 87 | { 88 | var destinationArray = new byte[nbytes]; 89 | 90 | if (ba1 != null) 91 | { 92 | Array.Copy(ba1, 0, destinationArray, 0, ba1.Length); 93 | } 94 | 95 | return destinationArray; 96 | } 97 | } 98 | } -------------------------------------------------------------------------------- /Source/GostCryptography.Tests/Pkcs/SignedCmsSignTest.cs: -------------------------------------------------------------------------------- 1 | using System.Security.Cryptography.Pkcs; 2 | using System.Security.Cryptography.X509Certificates; 3 | using System.Text; 4 | 5 | using GostCryptography.Pkcs; 6 | 7 | using NUnit.Framework; 8 | 9 | namespace GostCryptography.Tests.Pkcs 10 | { 11 | /// 12 | /// Подпись и проверка подписи сообщения CMS/PKCS#7. 13 | /// 14 | /// 15 | /// Тест создает сообщение, формирует подписанное сообщение в формате CMS/PKCS#7, 16 | /// а затем проверяет подпись полученную цифровую подпись. 17 | /// 18 | [TestFixture(Description = "Подпись и проверка подписи сообщения CMS/PKCS#7")] 19 | public class SignedCmsSignTest 20 | { 21 | [Test] 22 | [TestCaseSource(typeof(TestConfig), nameof(TestConfig.Gost_R3410_Certificates))] 23 | public void ShouldSign(TestCertificateInfo testCase) 24 | { 25 | // Given 26 | var certificate = testCase.Certificate; 27 | var message = CreateMessage(); 28 | 29 | // When 30 | var signedMessage = SignMessage(certificate, message); 31 | var isValidSignedMessage = VerifyMessage(signedMessage); 32 | 33 | // Then 34 | Assert.IsTrue(isValidSignedMessage); 35 | } 36 | 37 | private static byte[] CreateMessage() 38 | { 39 | // Некоторое сообщение для подписи 40 | 41 | return Encoding.UTF8.GetBytes("Some message to sign..."); 42 | } 43 | 44 | private static byte[] SignMessage(X509Certificate2 certificate, byte[] message) 45 | { 46 | // Создание объекта для подписи сообщения 47 | var signedCms = new GostSignedCms(new ContentInfo(message)); 48 | 49 | // Создание объект с информацией о подписчике 50 | var signer = new CmsSigner(certificate); 51 | 52 | // Включение информации только о конечном сертификате (только для теста) 53 | signer.IncludeOption = X509IncludeOption.EndCertOnly; 54 | 55 | // Создание подписи для сообщения CMS/PKCS#7 56 | signedCms.ComputeSignature(signer); 57 | 58 | // Создание сообщения CMS/PKCS#7 59 | return signedCms.Encode(); 60 | } 61 | 62 | private static bool VerifyMessage(byte[] signedMessage) 63 | { 64 | // Создание объекта для проверки подписи сообщения 65 | var signedCms = new GostSignedCms(); 66 | 67 | // Чтение сообщения CMS/PKCS#7 68 | signedCms.Decode(signedMessage); 69 | 70 | try 71 | { 72 | // Проверка подписи сообщения CMS/PKCS#7 73 | signedCms.CheckSignature(true); 74 | } 75 | catch 76 | { 77 | return false; 78 | } 79 | 80 | return true; 81 | } 82 | } 83 | } -------------------------------------------------------------------------------- /Source/GostCryptography.Tests/Data/SmevExample.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | MINECONOMSK_SYS_1 27 | Минэкономразвития СК 28 | 29 | 30 | 13312 31 | ФНС 32 | 33 | 34 | MINECONOMSK_SYS_1 35 | Минэкономразвития СК 36 | 37 | 2 38 | 2012-03-13T11:10:54.54Z 39 | 40 | 41 | 42 | <Документ xmlns="http://ws.unisoft/FNSINN/queryINNFL" ВерсФорм="4.01" ИдЗапрос="AB324006-978B-44D4-933D-C5E6DFA8A576"> 43 | <СвЮЛ ИННЮЛ="7825497650" НаимОрг="Нагрузочное тестирование" ОГРН="1037843048880"/> 44 | <СвФЛ ДатаРожд="12.07.1954" МестоРожд="РОССИЯ,,ГОРЬКОВСКАЯ ОБЛ.,АРЗАМАССКИЙ Р-Н,,НИКОЛЬСКОЕ С., ,,,"> 45 | <ФИО Имя="ПЕТР" Отчество="АЛЕКСЕЕВИЧ" Фамилия="ЧАХЛОВ"/> 46 | <УдЛичнФЛ ВыдДок="АРОВД" ДатаДок="16.11.2002" КодВидДок="21" СерНомДок="22 02 919928"/> 47 | 48 | 49 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /Source/GostCryptography/Asn1/Gost/Gost_R3410/Gost_R3410_PublicKeyParams.cs: -------------------------------------------------------------------------------- 1 | using GostCryptography.Asn1.Ber; 2 | using GostCryptography.Properties; 3 | 4 | namespace GostCryptography.Asn1.Gost.Gost_R3410 5 | { 6 | public abstract class Gost_R3410_PublicKeyParams : Asn1Type 7 | { 8 | public Asn1ObjectIdentifier PublicKeyParamSet { get; set; } 9 | 10 | public Asn1ObjectIdentifier DigestParamSet { get; set; } 11 | 12 | public Asn1ObjectIdentifier EncryptionParamSet { get; set; } 13 | 14 | 15 | public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength) 16 | { 17 | var elemLength = explicitTagging ? MatchTag(buffer, Asn1Tag.Sequence) : implicitLength; 18 | 19 | PublicKeyParamSet = null; 20 | DigestParamSet = null; 21 | EncryptionParamSet = null; 22 | 23 | var context = new Asn1BerDecodeContext(buffer, elemLength); 24 | var parsedLen = new IntHolder(); 25 | 26 | if (context.MatchElemTag(0, 0, ObjectIdentifierTypeCode, parsedLen, false)) 27 | { 28 | PublicKeyParamSet = new Asn1ObjectIdentifier(); 29 | PublicKeyParamSet.Decode(buffer, true, parsedLen.Value); 30 | } 31 | else 32 | { 33 | throw ExceptionUtility.CryptographicException(Resources.Asn1MissingRequiredException, buffer.ByteCount); 34 | } 35 | 36 | if (context.MatchElemTag(0, 0, ObjectIdentifierTypeCode, parsedLen, false)) 37 | { 38 | DigestParamSet = new Asn1ObjectIdentifier(); 39 | DigestParamSet.Decode(buffer, true, parsedLen.Value); 40 | } 41 | 42 | if (context.MatchElemTag(0, 0, ObjectIdentifierTypeCode, parsedLen, false)) 43 | { 44 | EncryptionParamSet = new Asn1ObjectIdentifier(); 45 | EncryptionParamSet.Decode(buffer, true, parsedLen.Value); 46 | } 47 | 48 | if (!context.Expired()) 49 | { 50 | var lastTag = buffer.PeekTag(); 51 | 52 | if (lastTag.Equals(0, 0, ObjectIdentifierTypeCode)) 53 | { 54 | throw ExceptionUtility.CryptographicException(Resources.Asn1SeqOrderException); 55 | } 56 | } 57 | } 58 | 59 | public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging) 60 | { 61 | var len = 0; 62 | 63 | if (EncryptionParamSet != null) 64 | { 65 | len += EncryptionParamSet.Encode(buffer, true); 66 | } 67 | 68 | if (DigestParamSet != null) 69 | { 70 | len += DigestParamSet.Encode(buffer, true); 71 | } 72 | 73 | len += PublicKeyParamSet.Encode(buffer, true); 74 | 75 | if (explicitTagging) 76 | { 77 | len += buffer.EncodeTagAndLength(Asn1Tag.Sequence, len); 78 | } 79 | 80 | return len; 81 | } 82 | } 83 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Reflection/CspKeyContainerInfoHelper.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Security.Cryptography; 3 | 4 | namespace GostCryptography.Reflection 5 | { 6 | static class CspKeyContainerInfoHelper 7 | { 8 | private static readonly object CspKeyContainerInfoConstructorSync = new object(); 9 | private static volatile ConstructorInfo _cspKeyContainerInfoConstructor; 10 | 11 | public static CspKeyContainerInfo CreateCspKeyContainerInfo(CspParameters parameters, bool randomKeyContainer) 12 | { 13 | CspKeyContainerInfo result = null; 14 | 15 | if (_cspKeyContainerInfoConstructor == null) 16 | { 17 | lock (CspKeyContainerInfoConstructorSync) 18 | { 19 | if (_cspKeyContainerInfoConstructor == null) 20 | { 21 | _cspKeyContainerInfoConstructor = typeof(CspKeyContainerInfo).GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic, null, new[] { typeof(CspParameters), typeof(bool) }, null); 22 | } 23 | } 24 | } 25 | 26 | if (_cspKeyContainerInfoConstructor != null) 27 | { 28 | try 29 | { 30 | result = (CspKeyContainerInfo)_cspKeyContainerInfoConstructor.Invoke(new object[] { parameters, randomKeyContainer }); 31 | } 32 | catch (TargetInvocationException exception) 33 | { 34 | if (exception.InnerException != null) 35 | { 36 | throw exception.InnerException; 37 | } 38 | 39 | throw; 40 | } 41 | 42 | if (result.KeyNumber == ((KeyNumber)(-1))) 43 | { 44 | var containerPatameters = GetCspKeyContainerInfoPatameters(result); 45 | containerPatameters.KeyNumber = (int)KeyNumber.Exchange; 46 | } 47 | } 48 | 49 | return result; 50 | } 51 | 52 | 53 | private static readonly object CspKeyContainerInfoPatametersFieldSync = new object(); 54 | private static volatile FieldInfo _cspKeyContainerInfoPatametersField; 55 | 56 | private static CspParameters GetCspKeyContainerInfoPatameters(CspKeyContainerInfo cspKeyContainerInfo) 57 | { 58 | CspParameters result = null; 59 | 60 | if (_cspKeyContainerInfoPatametersField == null) 61 | { 62 | lock (CspKeyContainerInfoPatametersFieldSync) 63 | { 64 | if (_cspKeyContainerInfoPatametersField == null) 65 | { 66 | _cspKeyContainerInfoPatametersField = typeof(CspKeyContainerInfo).GetField("m_parameters", BindingFlags.Instance | BindingFlags.NonPublic); 67 | } 68 | } 69 | } 70 | 71 | if (_cspKeyContainerInfoPatametersField != null) 72 | { 73 | result = _cspKeyContainerInfoPatametersField.GetValue(cspKeyContainerInfo) as CspParameters; 74 | } 75 | 76 | return result; 77 | } 78 | } 79 | } -------------------------------------------------------------------------------- /Source/GostCryptography.Tests/Pkcs/SignedCmsDetachedSignTest.cs: -------------------------------------------------------------------------------- 1 | using System.Security.Cryptography.Pkcs; 2 | using System.Security.Cryptography.X509Certificates; 3 | using System.Text; 4 | 5 | using GostCryptography.Pkcs; 6 | 7 | using NUnit.Framework; 8 | 9 | namespace GostCryptography.Tests.Pkcs 10 | { 11 | /// 12 | /// Подпись и проверка отсоединенной подписи сообщения CMS/PKCS#7. 13 | /// 14 | /// 15 | /// Тест создает сообщение, формирует отсоединенную подпись сообщения в формате CMS/PKCS#7, 16 | /// а затем проверяет подпись полученную цифровую подпись. 17 | /// 18 | [TestFixture(Description = "Подпись и проверка отсоединенной подписи сообщения CMS/PKCS#7")] 19 | public class SignedCmsDetachedSignTest 20 | { 21 | [Test] 22 | [TestCaseSource(typeof(TestConfig), nameof(TestConfig.Gost_R3410_Certificates))] 23 | public void ShouldSign(TestCertificateInfo testCase) 24 | { 25 | // Given 26 | var certificate = testCase.Certificate; 27 | var message = CreateMessage(); 28 | 29 | // When 30 | var detachedSignature = SignMessage(certificate, message); 31 | var isValidDetachedSignature = VerifyMessage(message, detachedSignature); 32 | 33 | // Then 34 | Assert.IsTrue(isValidDetachedSignature); 35 | } 36 | 37 | private static byte[] CreateMessage() 38 | { 39 | // Некоторое сообщение для подписи 40 | 41 | return Encoding.UTF8.GetBytes("Some message to sign..."); 42 | } 43 | 44 | private static byte[] SignMessage(X509Certificate2 certificate, byte[] message) 45 | { 46 | // Создание объекта для подписи сообщения 47 | var signedCms = new GostSignedCms(new ContentInfo(message), true); 48 | 49 | // Создание объект с информацией о подписчике 50 | var signer = new CmsSigner(certificate); 51 | 52 | // Включение информации только о конечном сертификате (только для теста) 53 | signer.IncludeOption = X509IncludeOption.EndCertOnly; 54 | 55 | // Создание подписи для сообщения CMS/PKCS#7 56 | signedCms.ComputeSignature(signer); 57 | 58 | // Создание подписи CMS/PKCS#7 59 | return signedCms.Encode(); 60 | } 61 | 62 | private static bool VerifyMessage(byte[] message, byte[] detachedSignature) 63 | { 64 | // Создание объекта для проверки подписи сообщения 65 | var signedCms = new GostSignedCms(new ContentInfo(message), true); 66 | 67 | // Чтение подписи CMS/PKCS#7 68 | signedCms.Decode(detachedSignature); 69 | 70 | try 71 | { 72 | // Проверка подписи CMS/PKCS#7 73 | signedCms.CheckSignature(true); 74 | } 75 | catch 76 | { 77 | return false; 78 | } 79 | 80 | return true; 81 | } 82 | } 83 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Asn1/Gost/Gost_28147_89/Gost_28147_89_EncryptedKey.cs: -------------------------------------------------------------------------------- 1 | using GostCryptography.Asn1.Ber; 2 | using GostCryptography.Properties; 3 | 4 | namespace GostCryptography.Asn1.Gost.Gost_28147_89 5 | { 6 | public sealed class Gost_28147_89_EncryptedKey : Asn1Type 7 | { 8 | public Gost_28147_89_Key EncryptedKey { get; set; } 9 | 10 | public Gost_28147_89_Mac MacKey { get; set; } 11 | 12 | public Gost_28147_89_Key MaskKey { get; set; } 13 | 14 | 15 | public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength) 16 | { 17 | var elemLength = explicitTagging ? MatchTag(buffer, Asn1Tag.Sequence) : implicitLength; 18 | 19 | EncryptedKey = null; 20 | MacKey = null; 21 | MaskKey = null; 22 | 23 | var context = new Asn1BerDecodeContext(buffer, elemLength); 24 | var parsedLen = new IntHolder(); 25 | 26 | if (!context.MatchElemTag(0, 0, OctetStringTypeCode, parsedLen, false)) 27 | { 28 | throw ExceptionUtility.CryptographicException(Resources.Asn1MissingRequiredException, buffer.ByteCount); 29 | } 30 | 31 | EncryptedKey = new Gost_28147_89_Key(); 32 | EncryptedKey.Decode(buffer, true, parsedLen.Value); 33 | 34 | if (context.MatchElemTag(0x80, 0, EocTypeCode, parsedLen, true)) 35 | { 36 | MaskKey = new Gost_28147_89_Key(); 37 | MaskKey.Decode(buffer, false, parsedLen.Value); 38 | } 39 | 40 | if (!context.MatchElemTag(0, 0, OctetStringTypeCode, parsedLen, false)) 41 | { 42 | throw ExceptionUtility.CryptographicException(Resources.Asn1MissingRequiredException, buffer.ByteCount); 43 | } 44 | 45 | MacKey = new Gost_28147_89_Mac(); 46 | MacKey.Decode(buffer, true, parsedLen.Value); 47 | 48 | if (MacKey.Length != 4) 49 | { 50 | throw ExceptionUtility.CryptographicException(Resources.Asn1ConsVioException, nameof(MacKey.Length), MacKey.Length); 51 | } 52 | } 53 | 54 | public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging) 55 | { 56 | var len = 0; 57 | 58 | if (MacKey.Length != 4) 59 | { 60 | throw ExceptionUtility.CryptographicException(Resources.Asn1ConsVioException, nameof(MacKey.Length), MacKey.Length); 61 | } 62 | 63 | len += MacKey.Encode(buffer, true); 64 | 65 | if (MaskKey != null) 66 | { 67 | var maskKeyLen = MaskKey.Encode(buffer, false); 68 | len += maskKeyLen; 69 | len += buffer.EncodeTagAndLength(0x80, 0, EocTypeCode, maskKeyLen); 70 | } 71 | 72 | len += EncryptedKey.Encode(buffer, true); 73 | 74 | if (explicitTagging) 75 | { 76 | len += buffer.EncodeTagAndLength(Asn1Tag.Sequence, len); 77 | } 78 | 79 | return len; 80 | } 81 | } 82 | } -------------------------------------------------------------------------------- /Source/GostCryptography.Tests/Gost_28147_89/Gost_28147_89_SymmetricAlgorithmTest.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | using System.Security.Cryptography; 3 | using System.Text; 4 | 5 | using GostCryptography.Base; 6 | using GostCryptography.Gost_28147_89; 7 | 8 | using NUnit.Framework; 9 | 10 | namespace GostCryptography.Tests.Gost_28147_89 11 | { 12 | /// 13 | /// Шифрование и дешифрование данных с использованием общего симметричного ключа ГОСТ 28147-89. 14 | /// 15 | /// 16 | /// Тест создает поток байт, шифрует его с использованием общего симметричного ключа, 17 | /// а затем дешифрует зашифрованные данные и проверяет корректность дешифрации. 18 | /// 19 | [TestFixture(Description = "Шифрование и дешифрование данных с использованием общего симметричного ключа ГОСТ 28147-89")] 20 | public class Gost_28147_89_SymmetricAlgorithmTest 21 | { 22 | [Test] 23 | [TestCaseSource(typeof(TestConfig), nameof(TestConfig.Providers))] 24 | public void ShouldEncryptAndDecrypt(ProviderType providerType) 25 | { 26 | // Given 27 | var sharedKey = new Gost_28147_89_SymmetricAlgorithm(providerType); 28 | var dataStream = CreateDataStream(); 29 | 30 | // When 31 | var encryptedDataStream = EncryptDataStream(sharedKey, dataStream); 32 | var decryptedDataStream = DecryptDataStream(sharedKey, encryptedDataStream); 33 | 34 | // Then 35 | Assert.That(dataStream, Is.EqualTo(decryptedDataStream)); 36 | } 37 | 38 | private static Stream CreateDataStream() 39 | { 40 | // Некоторый поток байт 41 | 42 | return new MemoryStream(Encoding.UTF8.GetBytes("Some data to encrypt...")); 43 | } 44 | 45 | private static Stream EncryptDataStream(SymmetricAlgorithm sharedKey, Stream dataStream) 46 | { 47 | var encryptedDataStream = new MemoryStream(); 48 | 49 | using (var encryptor = sharedKey.CreateEncryptor()) 50 | { 51 | var cryptoStream = new CryptoStream(encryptedDataStream, encryptor, CryptoStreamMode.Write); 52 | dataStream.CopyTo(cryptoStream); 53 | cryptoStream.FlushFinalBlock(); 54 | } 55 | 56 | encryptedDataStream.Position = 0; 57 | 58 | return encryptedDataStream; 59 | } 60 | 61 | private static Stream DecryptDataStream(SymmetricAlgorithm sharedKey, Stream encryptedDataStream) 62 | { 63 | var decryptedDataStream = new MemoryStream(); 64 | 65 | using (var decryptor = sharedKey.CreateDecryptor()) 66 | { 67 | var cryptoStream = new CryptoStream(encryptedDataStream, decryptor, CryptoStreamMode.Read); 68 | cryptoStream.CopyTo(decryptedDataStream); 69 | decryptedDataStream.Flush(); 70 | } 71 | 72 | decryptedDataStream.Position = 0; 73 | 74 | return decryptedDataStream; 75 | } 76 | } 77 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Gost_R3411/Gost_R3411_HashAlgorithm.cs: -------------------------------------------------------------------------------- 1 | using System.Security; 2 | 3 | using GostCryptography.Base; 4 | using GostCryptography.Native; 5 | 6 | namespace GostCryptography.Gost_R3411 7 | { 8 | /// 9 | /// Базовый класс для всех реализаций алгоритма хэширования ГОСТ Р 34.11. 10 | /// 11 | public abstract class Gost_R3411_HashAlgorithm : GostHashAlgorithm, ISafeHandleProvider 12 | { 13 | /// 14 | [SecuritySafeCritical] 15 | protected Gost_R3411_HashAlgorithm(int hashSize) : base(hashSize) 16 | { 17 | _hashHandle = CreateHashHandle(); 18 | } 19 | 20 | /// 21 | [SecuritySafeCritical] 22 | protected Gost_R3411_HashAlgorithm(ProviderType providerType, int hashSize) : base(providerType, hashSize) 23 | { 24 | _hashHandle = CreateHashHandle(); 25 | } 26 | 27 | [SecurityCritical] 28 | internal Gost_R3411_HashAlgorithm(ProviderType providerType, SafeProvHandleImpl providerHandle, int hashSize) : base(providerType, hashSize) 29 | { 30 | _hashHandle = CreateHashHandle(providerHandle); 31 | } 32 | 33 | 34 | /// 35 | /// Создает дескриптор функции хэширования криптографического провайдера. 36 | /// 37 | [SecurityCritical] 38 | protected SafeHashHandleImpl CreateHashHandle() 39 | { 40 | return CreateHashHandle(CryptoApiHelper.GetProviderHandle(ProviderType)); 41 | } 42 | 43 | /// 44 | /// Создает дескриптор функции хэширования криптографического провайдера. 45 | /// 46 | [SecurityCritical] 47 | protected abstract SafeHashHandleImpl CreateHashHandle(SafeProvHandleImpl providerHandle); 48 | 49 | 50 | [SecurityCritical] 51 | private SafeHashHandleImpl _hashHandle; 52 | 53 | /// 54 | SafeHashHandleImpl ISafeHandleProvider.SafeHandle 55 | { 56 | [SecurityCritical] 57 | get => _hashHandle; 58 | } 59 | 60 | 61 | /// 62 | [SecuritySafeCritical] 63 | public override void Initialize() 64 | { 65 | _hashHandle.TryDispose(); 66 | _hashHandle = CreateHashHandle(); 67 | } 68 | 69 | /// 70 | [SecuritySafeCritical] 71 | protected override void HashCore(byte[] data, int dataOffset, int dataLength) 72 | { 73 | CryptoApiHelper.HashData(_hashHandle, data, dataOffset, dataLength); 74 | } 75 | 76 | /// 77 | [SecuritySafeCritical] 78 | protected override byte[] HashFinal() 79 | { 80 | return CryptoApiHelper.EndHashData(_hashHandle); 81 | } 82 | 83 | /// 84 | [SecuritySafeCritical] 85 | protected override void Dispose(bool disposing) 86 | { 87 | _hashHandle.TryDispose(); 88 | 89 | base.Dispose(disposing); 90 | } 91 | } 92 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Reflection/EncryptedXmlHelper.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Reflection; 3 | using System.Security.Cryptography.Xml; 4 | using System.Xml; 5 | 6 | using GostCryptography.Properties; 7 | 8 | namespace GostCryptography.Reflection 9 | { 10 | static class EncryptedXmlHelper 11 | { 12 | private static readonly object DocumentFieldSync = new object(); 13 | private static volatile FieldInfo _documentField; 14 | 15 | public static XmlDocument GetDocument(this EncryptedXml encryptedXml) 16 | { 17 | if (_documentField == null) 18 | { 19 | lock (DocumentFieldSync) 20 | { 21 | if (_documentField == null) 22 | { 23 | _documentField = typeof(EncryptedXml).GetField("m_document", BindingFlags.Instance | BindingFlags.NonPublic); 24 | } 25 | } 26 | } 27 | 28 | if (_documentField == null) 29 | { 30 | throw ExceptionUtility.CryptographicException(Resources.XmlCannotFindPrivateMember, "m_document"); 31 | } 32 | 33 | return (XmlDocument)_documentField.GetValue(encryptedXml); 34 | } 35 | 36 | 37 | private static readonly object KeyNameMappingFieldSync = new object(); 38 | private static volatile FieldInfo _keyNameMappingField; 39 | 40 | public static Hashtable GetKeyNameMapping(this EncryptedXml encryptedXml) 41 | { 42 | if (_keyNameMappingField == null) 43 | { 44 | lock (KeyNameMappingFieldSync) 45 | { 46 | if (_keyNameMappingField == null) 47 | { 48 | _keyNameMappingField = typeof(EncryptedXml).GetField("m_keyNameMapping", BindingFlags.Instance | BindingFlags.NonPublic); 49 | } 50 | } 51 | } 52 | 53 | if (_keyNameMappingField == null) 54 | { 55 | throw ExceptionUtility.CryptographicException(Resources.XmlCannotFindPrivateMember, "m_keyNameMapping"); 56 | } 57 | 58 | return (Hashtable)_keyNameMappingField.GetValue(encryptedXml); 59 | } 60 | 61 | 62 | private static readonly object GetCipherValueMethodSync = new object(); 63 | private static volatile MethodInfo _getCipherValueMethod; 64 | 65 | public static byte[] GetCipherValue(this EncryptedXml encryptedXml, CipherData cipherData) 66 | { 67 | if (_getCipherValueMethod == null) 68 | { 69 | lock (GetCipherValueMethodSync) 70 | { 71 | if (_getCipherValueMethod == null) 72 | { 73 | _getCipherValueMethod = typeof(EncryptedXml).GetMethod("GetCipherValue", BindingFlags.Instance | BindingFlags.NonPublic); 74 | } 75 | } 76 | } 77 | 78 | if (_getCipherValueMethod == null) 79 | { 80 | throw ExceptionUtility.CryptographicException(Resources.XmlCannotFindPrivateMember, "GetCipherValue()"); 81 | } 82 | 83 | return (byte[])_getCipherValueMethod.Invoke(encryptedXml, new object[] { cipherData }); 84 | } 85 | } 86 | } -------------------------------------------------------------------------------- /Source/GostCryptography.Tests/Xml/Encrypt/EncryptedXmlCertificateTest.cs: -------------------------------------------------------------------------------- 1 | using System.Security.Cryptography.X509Certificates; 2 | using System.Xml; 3 | 4 | using GostCryptography.Tests.Properties; 5 | using GostCryptography.Xml; 6 | 7 | using NUnit.Framework; 8 | 9 | namespace GostCryptography.Tests.Xml.Encrypt 10 | { 11 | /// 12 | /// Шифрация и дешифрация XML документа с использованием сертификата. 13 | /// 14 | /// 15 | /// Тест создает XML-документ, выборочно шифрует элементы данного документа с использованием сертификата, 16 | /// а затем дешифрует полученный зашифрованный документ. 17 | /// 18 | [TestFixture(Description = "Шифрация и дешифрация XML документа с использованием сертификата")] 19 | public sealed class EncryptedXmlCertificateTest 20 | { 21 | [Test] 22 | [TestCaseSource(typeof(TestConfig), nameof(TestConfig.Gost_R3410_Certificates))] 23 | public void ShouldEncryptXml(TestCertificateInfo testCase) 24 | { 25 | // Given 26 | var certificate = testCase.Certificate; 27 | var xmlDocument = CreateXmlDocument(); 28 | var expectedXml = xmlDocument.OuterXml; 29 | 30 | // When 31 | var encryptedXmlDocument = EncryptXmlDocument(xmlDocument, certificate); 32 | var decryptedXmlDocument = DecryptXmlDocument(encryptedXmlDocument); 33 | var actualXml = decryptedXmlDocument.OuterXml; 34 | 35 | // Then 36 | Assert.AreEqual(expectedXml, actualXml); 37 | } 38 | 39 | private static XmlDocument CreateXmlDocument() 40 | { 41 | var document = new XmlDocument(); 42 | document.LoadXml(Resources.EncryptedXmlExample); 43 | return document; 44 | } 45 | 46 | private static XmlDocument EncryptXmlDocument(XmlDocument xmlDocument, X509Certificate2 certificate) 47 | { 48 | // Создание объекта для шифрации XML 49 | var encryptedXml = new GostEncryptedXml(); 50 | 51 | // Поиск элементов для шифрации 52 | var elements = xmlDocument.SelectNodes("//SomeElement[@Encrypt='true']"); 53 | 54 | if (elements != null) 55 | { 56 | foreach (XmlElement element in elements) 57 | { 58 | // Шифрация элемента 59 | var elementEncryptedData = encryptedXml.Encrypt(element, certificate); 60 | 61 | // Замена элемента его зашифрованным представлением 62 | GostEncryptedXml.ReplaceElement(element, elementEncryptedData, false); 63 | } 64 | } 65 | 66 | return xmlDocument; 67 | } 68 | 69 | private static XmlDocument DecryptXmlDocument(XmlDocument encryptedXmlDocument) 70 | { 71 | // Создание объекта для дешифрации XML 72 | var encryptedXml = new GostEncryptedXml(encryptedXmlDocument); 73 | 74 | // Расшифровка зашифрованных элементов документа 75 | encryptedXml.DecryptDocument(); 76 | 77 | return encryptedXmlDocument; 78 | } 79 | } 80 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Asn1/Ber/Asn1Tag.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Text; 3 | 4 | namespace GostCryptography.Asn1.Ber 5 | { 6 | [Serializable] 7 | public class Asn1Tag 8 | { 9 | public const short Universal = 0; 10 | public const short Private = 0xc0; 11 | public const short Application = 0x40; 12 | 13 | public const short Bit8Mask = 0x80; 14 | public const short ClassMask = 0xc0; 15 | public const short CONS = 0x20; 16 | public const short CTXT = 0x80; 17 | public const bool EXPL = true; 18 | public const short EXTIDCODE = 0x1f; 19 | public const short FormMask = 0x20; 20 | public const short IDMask = 0x1f; 21 | public const bool IMPL = false; 22 | public const short L7BitsMask = 0x7f; 23 | public const short PRIM = 0; 24 | 25 | public static readonly Asn1Tag Eoc = new Asn1Tag(0, 0, Asn1Type.EocTypeCode); 26 | public static readonly Asn1Tag Set = new Asn1Tag(0, 0x20, Asn1Type.SetTypeCode); 27 | public static readonly Asn1Tag Sequence = new Asn1Tag(0, 0x20, Asn1Type.SequenceTypeCode); 28 | public static readonly Asn1Tag Enumerated = new Asn1Tag(0, 0, Asn1Type.EnumeratedTypeCode); 29 | 30 | 31 | [NonSerialized] 32 | public short Class; 33 | 34 | [NonSerialized] 35 | public short Form; 36 | 37 | [NonSerialized] 38 | public int IdCode; 39 | 40 | 41 | public Asn1Tag() 42 | { 43 | Class = 0; 44 | Form = 0; 45 | IdCode = 0; 46 | } 47 | 48 | public Asn1Tag(short tagclass, short form, int idCode) 49 | { 50 | Class = tagclass; 51 | Form = form; 52 | IdCode = idCode; 53 | } 54 | 55 | public virtual bool Constructed 56 | { 57 | get { return (Form == 0x20); } 58 | } 59 | 60 | public bool Equals(Asn1Tag tag) 61 | { 62 | return Equals(tag.Class, tag.Form, tag.IdCode); 63 | } 64 | 65 | public virtual bool Equals(short tagclass, short form, int idCode) 66 | { 67 | return ((Class == tagclass) && (IdCode == idCode)); 68 | } 69 | 70 | public virtual bool IsEoc() 71 | { 72 | return Equals(0, 0, 0); 73 | } 74 | 75 | public override string ToString() 76 | { 77 | var builder = new StringBuilder(); 78 | builder.Append("["); 79 | 80 | switch (Class) 81 | { 82 | case 0x80: 83 | break; 84 | 85 | case Private: 86 | builder.Append("PRIVATE "); 87 | break; 88 | 89 | case Universal: 90 | builder.Append("UNIVERSAL "); 91 | break; 92 | 93 | case Application: 94 | builder.Append("APPLICATION "); 95 | break; 96 | 97 | default: 98 | builder.Append("??? "); 99 | break; 100 | } 101 | 102 | builder.Append(Convert.ToString(IdCode)); 103 | builder.Append("]"); 104 | 105 | return builder.ToString(); 106 | } 107 | } 108 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Base/GostExternalAsymmetricAlgorithm.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Security.Cryptography; 3 | 4 | using GostCryptography.Properties; 5 | 6 | namespace GostCryptography.Base 7 | { 8 | /// 9 | /// На базе заданного экземпляра пытается реализовать . 10 | /// Данный класс предназначен для интеграции со сторонними библиотеками и предназначен для внутреннего использования. 11 | /// 12 | sealed class GostExternalAsymmetricAlgorithm : GostAsymmetricAlgorithm 13 | { 14 | private readonly AsymmetricAlgorithm _algorithm; 15 | private readonly Func _createSignature; 16 | private readonly Func _verifySignature; 17 | 18 | 19 | public GostExternalAsymmetricAlgorithm(AsymmetricAlgorithm algorithm) : base(default(ProviderType), algorithm.KeySize) 20 | { 21 | var createSignatureMethod = algorithm.GetType().GetMethod(nameof(CreateSignature), new[] { typeof(byte[]) }); 22 | var verifySignatureMethod = algorithm.GetType().GetMethod(nameof(VerifySignature), new[] { typeof(byte[]), typeof(byte[]) }); 23 | 24 | if ((createSignatureMethod == null || createSignatureMethod.ReturnType != typeof(byte[])) 25 | || (verifySignatureMethod == null || verifySignatureMethod.ReturnType != typeof(bool))) 26 | { 27 | throw ExceptionUtility.Argument(nameof(algorithm), Resources.ShouldSupportGost3410); 28 | } 29 | 30 | _algorithm = algorithm; 31 | _createSignature = hash => (byte[])createSignatureMethod.Invoke(algorithm, new object[] { hash }); 32 | _verifySignature = (hash, signature) => (bool)verifySignatureMethod.Invoke(algorithm, new object[] { hash, signature }); 33 | } 34 | 35 | 36 | public override string AlgorithmName => _algorithm.SignatureAlgorithm; 37 | 38 | public override string SignatureAlgorithm => _algorithm.SignatureAlgorithm; 39 | 40 | public override string KeyExchangeAlgorithm => _algorithm.KeyExchangeAlgorithm; 41 | 42 | 43 | public override string ToXmlString(bool includePrivateKey) => _algorithm.ToXmlString(includePrivateKey); 44 | 45 | public override void FromXmlString(string keyParametersXml) => _algorithm.FromXmlString(keyParametersXml); 46 | 47 | 48 | public override byte[] CreateSignature(byte[] hash) => _createSignature(hash); 49 | 50 | public override bool VerifySignature(byte[] hash, byte[] signature) => _verifySignature(hash, signature); 51 | 52 | 53 | public override GostHashAlgorithm CreateHashAlgorithm() => throw ExceptionUtility.NotSupported(); 54 | 55 | public override GostKeyExchangeFormatter CreateKeyExchangeFormatter() => throw ExceptionUtility.NotSupported(); 56 | 57 | public override GostKeyExchangeDeformatter CreateKeyExchangeDeformatter() => throw ExceptionUtility.NotSupported(); 58 | } 59 | } -------------------------------------------------------------------------------- /Source/GostCryptography/Asn1/Gost/Gost_R3410/Gost_R3410_TransportParams.cs: -------------------------------------------------------------------------------- 1 | using GostCryptography.Asn1.Ber; 2 | using GostCryptography.Asn1.Gost.Gost_28147_89; 3 | using GostCryptography.Asn1.Gost.PublicKey; 4 | using GostCryptography.Properties; 5 | 6 | namespace GostCryptography.Asn1.Gost.Gost_R3410 7 | { 8 | public sealed class Gost_R3410_TransportParams : Asn1Type 9 | { 10 | public Asn1ObjectIdentifier EncryptionParamSet { get; set; } 11 | 12 | public SubjectPublicKeyInfo EphemeralPublicKey { get; set; } 13 | 14 | public Asn1OctetString Ukm { get; set; } 15 | 16 | 17 | public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength) 18 | { 19 | var elemLength = explicitTagging ? MatchTag(buffer, Asn1Tag.Sequence) : implicitLength; 20 | 21 | EncryptionParamSet = null; 22 | EphemeralPublicKey = null; 23 | Ukm = null; 24 | 25 | var context = new Asn1BerDecodeContext(buffer, elemLength); 26 | var parsedLen = new IntHolder(); 27 | 28 | if (!context.MatchElemTag(0, 0, ObjectIdentifierTypeCode, parsedLen, false)) 29 | { 30 | throw ExceptionUtility.CryptographicException(Resources.Asn1MissingRequiredException, buffer.ByteCount); 31 | } 32 | 33 | EncryptionParamSet = new Asn1ObjectIdentifier(); 34 | EncryptionParamSet.Decode(buffer, true, parsedLen.Value); 35 | 36 | if (context.MatchElemTag(0x80, 0x20, EocTypeCode, parsedLen, true)) 37 | { 38 | EphemeralPublicKey = new SubjectPublicKeyInfo(); 39 | EphemeralPublicKey.Decode(buffer, false, parsedLen.Value); 40 | } 41 | 42 | if (!context.MatchElemTag(0, 0, OctetStringTypeCode, parsedLen, false)) 43 | { 44 | throw ExceptionUtility.CryptographicException(Resources.Asn1MissingRequiredException, buffer.ByteCount); 45 | } 46 | 47 | Ukm = new Asn1OctetString(); 48 | Ukm.Decode(buffer, true, parsedLen.Value); 49 | 50 | if (Ukm.Length != 8) 51 | { 52 | throw ExceptionUtility.CryptographicException(Resources.Asn1ConsVioException, nameof(Ukm.Length), Ukm.Length); 53 | } 54 | } 55 | 56 | public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging) 57 | { 58 | var len = 0; 59 | 60 | if (Ukm.Length != 8) 61 | { 62 | throw ExceptionUtility.CryptographicException(Resources.Asn1ConsVioException, nameof(Ukm.Length), Ukm.Length); 63 | } 64 | 65 | len += Ukm.Encode(buffer, true); 66 | 67 | if (EphemeralPublicKey != null) 68 | { 69 | var epkLength = EphemeralPublicKey.Encode(buffer, false); 70 | 71 | len += epkLength; 72 | len += buffer.EncodeTagAndLength(0x80, 0x20, EocTypeCode, epkLength); 73 | } 74 | 75 | len += EncryptionParamSet.Encode(buffer, true); 76 | 77 | if (explicitTagging) 78 | { 79 | len += buffer.EncodeTagAndLength(Asn1Tag.Sequence, len); 80 | } 81 | 82 | return len; 83 | } 84 | } 85 | } -------------------------------------------------------------------------------- /Source/GostCryptography.Tests/Sign/SignDataStreamSignatureFormatterTest.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | using System.Security.Cryptography.X509Certificates; 3 | using System.Text; 4 | 5 | using GostCryptography.Base; 6 | 7 | using NUnit.Framework; 8 | 9 | namespace GostCryptography.Tests.Sign 10 | { 11 | /// 12 | /// Подпись и проверка подписи потока байт с помощью сертификата и классов форматирования. 13 | /// 14 | /// 15 | /// Тест создает поток байт, вычисляет цифровую подпись потока байт с использованием закрытого ключа сертификата, 16 | /// а затем с помощью открытого ключа сертификата проверяет полученную подпись. Для вычисления цифровой подписи 17 | /// используется класс , для проверки цифровой подписи используется класс 18 | /// . 19 | /// 20 | [TestFixture(Description = "Подпись и проверка подписи потока байт с помощью сертификата и классов форматирования")] 21 | public class SignDataStreamSignatureFormatterTest 22 | { 23 | [Test] 24 | [TestCaseSource(typeof(TestConfig), nameof(TestConfig.Gost_R3410_Certificates))] 25 | public void ShouldSignDataStream(TestCertificateInfo testCase) 26 | { 27 | // Given 28 | var certificate = testCase.Certificate; 29 | var privateKey = (GostAsymmetricAlgorithm)certificate.GetPrivateKeyAlgorithm(); 30 | var publicKey = (GostAsymmetricAlgorithm)certificate.GetPublicKeyAlgorithm(); 31 | var dataStream = CreateDataStream(); 32 | 33 | // When 34 | 35 | dataStream.Seek(0, SeekOrigin.Begin); 36 | var signature = CreateSignature(privateKey, dataStream); 37 | 38 | dataStream.Seek(0, SeekOrigin.Begin); 39 | var isValidSignature = VerifySignature(publicKey, dataStream, signature); 40 | 41 | // Then 42 | Assert.IsTrue(isValidSignature); 43 | } 44 | 45 | private static Stream CreateDataStream() 46 | { 47 | // Некоторый поток байт для подписи 48 | 49 | return new MemoryStream(Encoding.UTF8.GetBytes("Some data to sign...")); 50 | } 51 | 52 | private static byte[] CreateSignature(GostAsymmetricAlgorithm privateKey, Stream dataStream) 53 | { 54 | byte[] hash; 55 | 56 | using (var hashAlg = privateKey.CreateHashAlgorithm()) 57 | { 58 | hash = hashAlg.ComputeHash(dataStream); 59 | } 60 | 61 | var formatter = new GostSignatureFormatter(privateKey); 62 | 63 | return formatter.CreateSignature(hash); 64 | } 65 | 66 | private static bool VerifySignature(GostAsymmetricAlgorithm publicKey, Stream dataStream, byte[] signature) 67 | { 68 | byte[] hash; 69 | 70 | using (var hashAlg = publicKey.CreateHashAlgorithm()) 71 | { 72 | hash = hashAlg.ComputeHash(dataStream); 73 | } 74 | 75 | var deformatter = new GostSignatureDeformatter(publicKey); 76 | 77 | return deformatter.VerifySignature(hash, signature); 78 | } 79 | } 80 | } --------------------------------------------------------------------------------