public void Encrypt2012_256() { using (Gost3410_2012_256 gost = GetGost2012_256Provider()) { Encrypt(gost); } }
public static X509Certificate2 CopyWithPrivateKey(this X509Certificate2 certificate, Gost3410_2012_256 privateKey) { if (certificate == null) { throw new ArgumentNullException(nameof(certificate)); } if (privateKey == null) { throw new ArgumentNullException(nameof(privateKey)); } if (certificate.HasPrivateKey) { throw new InvalidOperationException(SR.Cryptography_Cert_AlreadyHasPrivateKey); } using (Gost3410_2012_256 publicKey = GetGost3410_2012_256PublicKey(certificate)) { if (publicKey == null) { throw new ArgumentException(SR.Cryptography_PrivateKey_WrongAlgorithm); } //Gost3410Parameters currentParameters = publicKey.ExportParameters(false); //Gost3410Parameters newParameters = privateKey.ExportParameters(false); } ICertificatePal pal = certificate.Pal.CopyWithPrivateKey(privateKey); return(new X509Certificate2(pal)); }
// Шифрование тестового файла. static void EncryptTestFile( Gost3410_2012_256 publicKey, Gost3410_2012_256CryptoServiceProvider privateKey, string fileId = "2012_256") { // Создаем симметричный ключ. Gost28147 symmetric = Gost28147.Create(); // Открываем ключ отправителя. Gost3410Parameters srcPublicKeyParameters = privateKey.ExportParameters(false); // Создаем agree ключ GostSharedSecretAlgorithm agree = privateKey.CreateAgree( publicKey.ExportParameters(false)); // Зашифровываем симметричный ключ на agree ключе. byte[] WrappedKey = agree.Wrap(symmetric, GostKeyWrapMethod.CryptoPro12KeyWrap); // Создаем поток шифратора. ICryptoTransform transform = symmetric.CreateEncryptor(); // Создаем зашифрованный файл. using (FileStream ofs = new FileStream(string.Format(EncryptedFileName, fileId), FileMode.Create)) { BinaryWriter bw = new BinaryWriter(ofs); // Записываем зашифрованный симметричный ключ. bw.Write(WrappedKey.Length); bw.Write(WrappedKey); // Записываем синхропосылку bw.Write(symmetric.IV.Length); bw.Write(symmetric.IV); // Передаем открытый ключ. BinaryFormatter formatter = new BinaryFormatter(); formatter.Serialize(ofs, srcPublicKeyParameters); // Создаем поток шифрования для записи в файл. using (CryptoStream cs = new CryptoStream(ofs, transform, CryptoStreamMode.Write)) { byte[] data = new byte[4096]; // Открываем входной файл. using (FileStream ifs = new FileStream(string.Format(SourceFileName, fileId), FileMode.Open, FileAccess.Read)) { // и переписываем содержимое в выходной поток. int length = ifs.Read(data, 0, data.Length); while (length > 0) { cs.Write(data, 0, length); length = ifs.Read(data, 0, data.Length); } } } } }
/// <summary> /// Create a self-signed certificate using the established subject, key, and optional /// extensions. /// </summary> /// <param name="notBefore"> /// The oldest date and time where this certificate is considered valid. /// Typically <see cref="DateTimeOffset.UtcNow"/>, plus or minus a few seconds. /// </param> /// <param name="notAfter"> /// The date and time where this certificate is no longer considered valid. /// </param> /// <returns> /// An <see cref="X509Certificate2"/> with the specified values. The returned object will /// assert <see cref="X509Certificate2.HasPrivateKey" />. /// </returns> /// <exception cref="ArgumentException"> /// <paramref name="notAfter"/> represents a date and time before <paramref name="notAfter"/>. /// </exception> /// <exception cref="InvalidOperationException"> /// A constructor was used which did not accept a signing key. /// </exception>> /// <exception cref="CryptographicException"> /// Other errors during the certificate creation process. /// </exception> public X509Certificate2 CreateSelfSigned(DateTimeOffset notBefore, DateTimeOffset notAfter) { if (notAfter < notBefore) { throw new ArgumentException(SR.Cryptography_CertReq_DatesReversed); } if (_key == null) { throw new InvalidOperationException(SR.Cryptography_CertReq_NoKeyProvided); } Debug.Assert(_generator != null); byte[] serialNumber = new byte[8]; RandomNumberGenerator.Fill(serialNumber); using (X509Certificate2 certificate = Create( SubjectName, _generator, notBefore, notAfter, serialNumber)) { RSA rsa = _key as RSA; if (rsa != null) { return(certificate.CopyWithPrivateKey(rsa)); } ECDsa ecdsa = _key as ECDsa; if (ecdsa != null) { return(certificate.CopyWithPrivateKey(ecdsa)); } Gost3410 gost3410 = _key as Gost3410; if (gost3410 != null) { return(certificate.CopyWithPrivateKey(gost3410)); } Gost3410_2012_256 gost3410_2012_256 = _key as Gost3410_2012_256; if (gost3410_2012_256 != null) { return(certificate.CopyWithPrivateKey(gost3410_2012_256)); } Gost3410_2012_512 gost3410_2012_512 = _key as Gost3410_2012_512; if (gost3410_2012_512 != null) { return(certificate.CopyWithPrivateKey(gost3410_2012_512)); } } Debug.Fail($"Key was of no known type: {_key?.GetType().FullName ?? "null"}"); throw new CryptographicException(); }
public static X509SignatureGenerator CreateForGost(Gost3410_2012_256 key) { if (key == null) { throw new ArgumentNullException(nameof(key)); } return(new Gost3410_2012_256SignatureGenerator(key)); }
private static void EncriptFile(X509Certificate2 sert, string sourceFile, string encFile) { var publicKey = (Gost3410_2012_256CryptoServiceProvider)sert.PublicKey.Key; var asymmetricAlg = publicKey as Gost3410_2012_256; if (asymmetricAlg == null) { throw new CryptographicException("Not a gost certificate"); } var symmetricKey = Gost28147.Create(); Gost3410_2012_256 senderRndKey = Gost3410_2012_256.Create(); Gost3410Parameters senderRndKeyParameters = senderRndKey.ExportParameters(false); GostSharedSecretAlgorithm agreeKey = senderRndKey.CreateAgree(asymmetricAlg.ExportParameters(false)); var encodedSymmetricKey = agreeKey.Wrap(symmetricKey, GostKeyWrapMethod.CryptoProKeyWrap); ICryptoTransform transform = symmetricKey.CreateEncryptor(); using (FileStream writer = new FileStream(encFile, FileMode.Create)) { BinaryWriter binaryWriter = new BinaryWriter(writer); binaryWriter.Write(encodedSymmetricKey.Length); binaryWriter.Write(encodedSymmetricKey); binaryWriter.Write(symmetricKey.IV.Length); binaryWriter.Write(symmetricKey.IV); BinaryFormatter binaryFormatter = new BinaryFormatter(); binaryFormatter.Serialize(writer, senderRndKeyParameters); using (CryptoStream cryptoStream = new CryptoStream(writer, transform, CryptoStreamMode.Write)) { var buffer = new byte[100]; using (FileStream reader = new FileStream(sourceFile, FileMode.Open, FileAccess.Read)) { var length = reader.Read(buffer, 0, buffer.Length); while (length > 0) { cryptoStream.Write(buffer, 0, buffer.Length); length = reader.Read(buffer, 0, buffer.Length); } } } } }
/// <summary> /// Устанавливает секретный ключ. /// </summary> /// /// <param name="key">Объект класса AsymmetricAlgorithm, /// содержащий секретный ключ.</param> /// /// <remarks><para>Ключ должен быть установлен до вызова /// функций восстановления ключа.</para> /// </remarks> /// /// <argnull name="key" /> /// <exception cref="CryptographicException"> /// <paramref name="key"/> не поддерживает алгоритм /// <see cref="Gost3410_2012_256"/>.</exception> public override void SetKey(AsymmetricAlgorithm key) { if (key == null) { throw new ArgumentNullException("key"); } Gost3410_2012_256 gost = key as Gost3410_2012_256; if (gost == null) { throw new CryptographicException( Resources.Cryptography_Assymmetric_GOST3410_2012_256); } gostKey_ = gost; }
public void TestKeyExchange2012_256() { // Ассиметричный ключ получателя. Gost3410_2012_256 AssymKey; // Синхропосылка. byte[] IV; // Создаем случайный открытый ключ. using (Gost3410_2012_256 gkey = GetGostProvider2012_256()) { AssymKey = gkey; // Создаем случайный секретный ключ, который необходимо передать. Gost28147 key = new Gost28147CryptoServiceProvider(); // Синхропосылка не входит в GostKeyTransport и должна // передаваться отдельно. IV = key.IV; // Создаем форматтер, шифрующий на ассиметричном ключе получателя. GostKeyExchangeFormatter Formatter = new GostKeyExchangeFormatter(AssymKey); // GostKeyTransport - формат зашифрованной для безопасной передачи // ключевой информации. GostKeyTransport encKey = Formatter.CreateKeyExchange(key); // Шифруемая строка string message = "012345678901234567890"; byte[] sourceBytes = Encoding.ASCII.GetBytes(message); Console.WriteLine("** Строка до шифрования: " + message); // Шифруем строку на сессионном ключе byte[] encBytes = GostEncrypt(key, sourceBytes); Console.WriteLine("** Строка после шифрования: " + Encoding.ASCII.GetString(encBytes)); // Получатель расшифровывает GostKeyTransport и само сообщение. byte[] decBytes = GostDecrypt(encKey, encBytes, IV, AssymKey); Console.WriteLine("** Строка после расшифрования: " + Encoding.ASCII.GetString(decBytes)); Assert.Equal(sourceBytes, decBytes); } }
/// <summary> /// Create a CertificateRequest for the specified subject name, GOST3410_2012_256 key, and hash algorithm. /// </summary> /// <param name="subjectName"> /// The parsed representation of the subject name for the certificate or certificate request. /// </param> /// <param name="key"> /// n GOST3410 key whose public key material will be included in the certificate or certificate request. /// This key will be used as a private key if <see cref="CreateSelfSigned" /> is called. /// </param> /// <param name="hashAlgorithm"> /// The hash algorithm to use when signing the certificate or certificate request. /// </param> public CertificateRequest(X500DistinguishedName subjectName, Gost3410_2012_256 key, HashAlgorithmName hashAlgorithm) { if (subjectName == null) { throw new ArgumentNullException(nameof(subjectName)); } if (key == null) { throw new ArgumentNullException(nameof(key)); } if (string.IsNullOrEmpty(hashAlgorithm.Name)) { throw new ArgumentException(SR.Cryptography_HashAlgorithmNameNullOrEmpty, nameof(hashAlgorithm)); } SubjectName = subjectName; _key = key; _generator = X509SignatureGenerator.CreateForGost(key); PublicKey = _generator.PublicKey; HashAlgorithm = hashAlgorithm; }
/// <summary> /// Инициализирует новый экземпляр класса <c>GostKeyValue</c> с заданным /// открытым ключом ГОСТ 34.10-2012 256. /// </summary> /// /// <param name="key">Экземпляр реализации класса /// <see cref="Gost2012_256KeyValue"/>, в котором содержится открытый /// ключ.</param> public Gost2012_256KeyValue(Gost3410_2012_256 key) { _key = key; }
/// <summary> /// Инициализирует новый экземпляр класса <c>GostKeyValue</c> с новым, /// сгенерированным случайным образом открытым ключом ГОСТ 34.10-2012 256. /// </summary> /// <remarks>При создании нового ключа ГОСТ 34.10-2012 256 этот конструктор /// использует реализацию <see cref="Gost3410_2012_256"/> по /// умолчанию, как определено классом /// <see cref="System.Security.Cryptography.CryptoConfig"/>.</remarks> public Gost2012_256KeyValue() { _key = (Gost3410_2012_256)Gost3410_2012_256.Create(); }
/// <summary> /// Create a certificate using the established subject, key, and optional extensions using /// the provided certificate as the issuer. /// </summary> /// <param name="issuerCertificate"> /// An X509Certificate2 instance representing the issuing Certificate Authority (CA). /// </param> /// <param name="notBefore"> /// The oldest date and time where this certificate is considered valid. /// Typically <see cref="DateTimeOffset.UtcNow"/>, plus or minus a few seconds. /// </param> /// <param name="notAfter"> /// The date and time where this certificate is no longer considered valid. /// </param> /// <param name="serialNumber"> /// The serial number to use for the new certificate. This value should be unique per issuer. /// The value is interpreted as an unsigned (big) integer in big endian byte ordering. /// </param> /// <returns> /// An <see cref="X509Certificate2"/> with the specified values. The returned object will /// not assert <see cref="X509Certificate2.HasPrivateKey" />. /// </returns> /// <exception cref="ArgumentNullException"><paramref name="issuerCertificate"/> is null.</exception> /// <exception cref="ArgumentException"> /// The <see cref="X509Certificate2.HasPrivateKey"/> value for <paramref name="issuerCertificate"/> is false. /// </exception> /// <exception cref="ArgumentException"> /// The type of signing key represented by <paramref name="issuerCertificate"/> could not be determined. /// </exception> /// <exception cref="ArgumentException"> /// <paramref name="notAfter"/> represents a date and time before <paramref name="notBefore"/>. /// </exception> /// <exception cref="ArgumentException"><paramref name="serialNumber"/> is null or has length 0.</exception> /// <exception cref="ArgumentException"> /// <paramref name="issuerCertificate"/> has a different key algorithm than the requested certificate. /// </exception> /// <exception cref="InvalidOperationException"> /// <paramref name="issuerCertificate"/> is an RSA certificate and this object was created via a constructor /// which does not accept a <see cref="RSASignaturePadding"/> value. /// </exception> public X509Certificate2 Create( X509Certificate2 issuerCertificate, DateTimeOffset notBefore, DateTimeOffset notAfter, byte[] serialNumber) { if (issuerCertificate == null) { throw new ArgumentNullException(nameof(issuerCertificate)); } if (!issuerCertificate.HasPrivateKey) { throw new ArgumentException(SR.Cryptography_CertReq_IssuerRequiresPrivateKey, nameof(issuerCertificate)); } if (notAfter < notBefore) { throw new ArgumentException(SR.Cryptography_CertReq_DatesReversed); } if (serialNumber == null || serialNumber.Length < 1) { throw new ArgumentException(SR.Arg_EmptyOrNullArray, nameof(serialNumber)); } if (issuerCertificate.PublicKey.Oid.Value != PublicKey.Oid.Value) { throw new ArgumentException( SR.Format( SR.Cryptography_CertReq_AlgorithmMustMatch, issuerCertificate.PublicKey.Oid.Value, PublicKey.Oid.Value), nameof(issuerCertificate)); } DateTime notBeforeLocal = notBefore.LocalDateTime; if (notBeforeLocal < issuerCertificate.NotBefore) { throw new ArgumentException( SR.Format( SR.Cryptography_CertReq_NotBeforeNotNested, notBeforeLocal, issuerCertificate.NotBefore), nameof(notBefore)); } DateTime notAfterLocal = notAfter.LocalDateTime; // Round down to the second, since that's the cert accuracy. // This makes one method which uses the same DateTimeOffset for chained notAfters // not need to do the rounding locally. long notAfterLocalTicks = notAfterLocal.Ticks; long fractionalSeconds = notAfterLocalTicks % TimeSpan.TicksPerSecond; notAfterLocalTicks -= fractionalSeconds; notAfterLocal = new DateTime(notAfterLocalTicks, notAfterLocal.Kind); if (notAfterLocal > issuerCertificate.NotAfter) { throw new ArgumentException( SR.Format( SR.Cryptography_CertReq_NotAfterNotNested, notAfterLocal, issuerCertificate.NotAfter), nameof(notAfter)); } // Check the Basic Constraints and Key Usage extensions to help identify inappropriate certificates. // Note that this is not a security check. The system library backing X509Chain will use these same criteria // to determine if a chain is valid; and a user can easily call the X509SignatureGenerator overload to // bypass this validation. We're simply helping them at signing time understand that they've // chosen the wrong cert. var basicConstraints = (X509BasicConstraintsExtension)issuerCertificate.Extensions[Oids.BasicConstraints2]; var keyUsage = (X509KeyUsageExtension)issuerCertificate.Extensions[Oids.KeyUsage]; if (basicConstraints == null) { throw new ArgumentException(SR.Cryptography_CertReq_BasicConstraintsRequired, nameof(issuerCertificate)); } if (!basicConstraints.CertificateAuthority) { throw new ArgumentException(SR.Cryptography_CertReq_IssuerBasicConstraintsInvalid, nameof(issuerCertificate)); } if (keyUsage != null && (keyUsage.KeyUsages & X509KeyUsageFlags.KeyCertSign) == 0) { throw new ArgumentException(SR.Cryptography_CertReq_IssuerKeyUsageInvalid, nameof(issuerCertificate)); } AsymmetricAlgorithm key = null; string keyAlgorithm = issuerCertificate.GetKeyAlgorithm(); X509SignatureGenerator generator; try { switch (keyAlgorithm) { case Oids.Rsa: if (_rsaPadding == null) { throw new InvalidOperationException(SR.Cryptography_CertReq_RSAPaddingRequired); } RSA rsa = issuerCertificate.GetRSAPrivateKey(); key = rsa; generator = X509SignatureGenerator.CreateForRSA(rsa, _rsaPadding); break; case Oids.EcPublicKey: ECDsa ecdsa = issuerCertificate.GetECDsaPrivateKey(); key = ecdsa; generator = X509SignatureGenerator.CreateForECDsa(ecdsa); break; //begin: gost case Oids.Gost3410EL: Gost3410 gost3410 = issuerCertificate.GetGost3410PrivateKey(); key = gost3410; generator = X509SignatureGenerator.CreateForGost(gost3410); break; case Oids.Gost3410_2012_256: Gost3410_2012_256 gost3410_2012_256 = issuerCertificate.GetGost3410_2012_256PrivateKey(); key = gost3410_2012_256; generator = X509SignatureGenerator.CreateForGost(gost3410_2012_256); break; case Oids.Gost3410_2012_512: Gost3410_2012_512 gost3410_2012_512 = issuerCertificate.GetGost3410_2012_512PrivateKey(); key = gost3410_2012_512; generator = X509SignatureGenerator.CreateForGost(gost3410_2012_512); break; //end: gost default: throw new ArgumentException( SR.Format(SR.Cryptography_UnknownKeyAlgorithm, keyAlgorithm), nameof(issuerCertificate)); } return(Create(issuerCertificate.SubjectName, generator, notBefore, notAfter, serialNumber)); } finally { key?.Dispose(); } }
public ICertificatePal CopyWithPrivateKey(Gost3410_2012_256 gost) { return(CopyWithPersistedCapiKey(((Gost3410_2012_256CryptoServiceProvider)gost).CspKeyContainerInfo)); }
internal Gost3410_2012_256SignatureGenerator(Gost3410_2012_256 key) { Debug.Assert(key != null); _key = key; }
public byte[] DecryptMessage() { X509Certificate2 cert = GetCertificate(); Gost3410_2012_256 assym = cert.PrivateKey as Gost3410_2012_256; var s_parts = encryptedSessionKey.Split(':'); var parts = encryptedSessionKey.Split(':').Select(part => part.Split(' ').Select(e => Convert.ToByte(e, 16)).ToArray()).ToArray(); //0 - Параметры шифрования ключа обмена. Компонент является результатом выполнения CryptGetKeyParam(KP_CIPHEROID). //1 - Эфемерный открытый ключ, который использовался для выработки ключа обмена. Компонент является результатом выполнения CryptExportKey(PUBLICKEYBLOBEX). //2 - Симметричный ключ, зашифрованный на ключе обмена. Компонент является результатом выполнения CryptExportKey(SIMPLEBLOB). // // -=PUBLICKEYBLOB=- // BYTE bPublicKeyBlob[] = // { // 0x06, // bType = PUBLICKEYBLOB // 0x20, // bVersion = 0x20 // 0x00, 0x00, // reserved // 0x23, 0x2E, 0x00, 0x00, // KeyAlg = ALG_SID_GR3410EL // 0x4D, 0x41, 0x47, 0x31, // Magic = GR3410_1_MAGIC // 0x00, 0x02, 0x00, 0x00, // BitLen = 512 // bASN1GostR3410_94_PublicKeyParameters // 0x30, 0x12, // 0x06, 0x07, // 0x2A, 0x85, 0x03, 0x02, 0x02, 0x24, 0x00, // 0x06, 0x07, // 0x2A, 0x85, 0x03, 0x02, 0x02, 0x1E, 0x01, // bPublicKey // 0x2D, 0xC3, 0xFD, 0xF6, 0x9C, 0x91, 0x3D, 0xCC, // 0xB6, 0x53, 0x26, 0x8E, 0x51, 0x2F, 0x5E, 0xDD, // 0xE4, 0x1A, 0x5D, 0xB3, 0x58, 0x3C, 0xDF, 0x60, // 0x68, 0xF2, 0x48, 0xA2, 0xB0, 0xB8, 0xDE, 0x7B, // 0xC9, 0xAA, 0x20, 0xE3, 0xCF, 0x63, 0xDF, 0x5F, // 0x39, 0x55, 0x21, 0xE0, 0xA0, 0xDD, 0x85, 0x3E, // 0x0A, 0xAF, 0x44, 0xFA, 0x49, 0x3C, 0xD5, 0x4C, // 0xA8, 0x04, 0x8D, 0x1D, 0x9C, 0x41, 0x85, 0xFB // }; // // BYTE bEncryptionParamSet[] = { // 0x30, 0x09, // SEQUENCE (размер 0x09) // 0x06, 0x07, // OBJECT IDENTIFIER, (размер 0x07) // 0x2a, 0x85, 0x03, 0x02, 0x02, 0x1f, 0x01 // 1.2.643.2.2.31.1 // }; // -=SIMPLEBLOB=- // BYTE bSimpleBlob[] = // { // 0x01, // bType = SIMPLEBLOB // 0x20, // bVersion = 0x20 // 0x00, 0x00, // reserved // 0x23, 0x2e, 0x00, 0x00, // KeyAlg = ALG_SID_GR3410EL // 0x4d, 0x41, 0x47, 0x31, // Magic = GR3410_1_MAGIC // 0x1e, 0x66, 0x00, 0x00, // EncryptKeyAlgId = CALG_G28147 // 0x76, 0xee, 0xb4, 0x6b, 0x1b, 0x10, 0x36, 0xeb, // bUKM // // pbEncryptedKey // 0x5e, 0x70, 0x73, 0x5f, 0x36, 0x98, 0xb4, 0x35, // 0x5b, 0x45, 0x03, 0x7f, 0xa7, 0xce, 0x00, 0x97, // 0x11, 0x5e, 0x45, 0xc6, 0x58, 0x59, 0x94, 0x72, // 0x66, 0x42, 0x06, 0x3f, 0x72, 0x3a, 0xb4, 0x9e, // 0x8c, 0x86, 0x08, 0x84, // pbMacKey // 0x30, 0x09, 0x06, 0x07, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x1f, 0x01 // bEncryptionParamSet // }; Gost2012_256KeyExchangeDeformatter Deformatter = new Gost2012_256KeyExchangeDeformatter(assym); GostKeyTransport encKey = new GostKeyTransport(); //0- 31 2E 32 2E 36 34 33 2E 37 2E 31 2E 32 2E 35 2E 31 2E 31 00 //1- 0A 20 00 00 49 2E 00 00 4D 41 47 31 00 02 00 00 30 13 06 07 2A 85 03 02 02 24 00 06 08 2A 85 03 07 01 01 02 02 8B FF 19 01 0B CF BB C9 03 59 58 D0 6F 24 C1 3C 5D 1F AC 9B F8 F7 24 7B 48 4E 39 2E 9A 42 B6 66 60 CA D8 0E 62 7E 22 15 CC C9 E5 A6 2E 58 FF 9B 1D FB EA 7B 5E 42 B5 FD 51 97 BD D9 6E 24 16 AC // //0A PUBLICKEYBLOBEX //20 Version //00 00 Reserved //49 2E 00 00 // KeyAlg = ??? //4D 41 47 31 // Magic = GR3410_1_MAGIC //00 02 00 00 // EncryptKeyAlgId //30 ??? //13 Length for Oids //06 07 2A 85 03 02 02 24 00 // OId ??? 1.2.643.2.2.36.0 PublicKeyParamSet //06 08 2A 85 03 07 01 01 02 02 // OId ??? 1.2.643.7.1.1.2.2 DigestParamSet //8B FF 19 01 0B CF BB C9 //PublicKey //03 59 58 D0 6F 24 C1 3C //5D 1F AC 9B F8 F7 24 7B //48 4E 39 2E 9A 42 B6 66 //60 CA D8 0E 62 7E 22 15 //CC C9 E5 A6 2E 58 FF 9B //1D FB EA 7B 5E 42 B5 FD //51 97 BD D9 6E 24 16 AC // //2- 01 20 00 00 1E 66 00 00 FD 51 4A 37 1E 66 00 00 6A 0F 44 24 B6 CB 8B 7C 91 8B D1 55 2D 7D 07 67 6F 03 42 8E DC BE D0 9B 84 BA 8E 04 E7 FA 3A 2A 9B 2C F6 F1 71 86 3D F6 4E 32 52 65 30 09 06 07 2A 85 03 02 02 1F 01" // //01 SIMPLEBLOB //20 Version //00 00 Reserved //1E 66 00 00 KeyAlg //FD 51 4A 37 Magic //1E 66 00 00 EncryptKeyAlgId //6A 0F 44 24 B6 CB 8B 7C UKM //91 8B D1 55 2D 7D 07 67 EncryptedKey //6F 03 42 8E DC BE D0 9B //84 BA 8E 04 E7 FA 3A 2A //9B 2C F6 F1 71 86 3D F6 //4E 32 52 65 MacKey //30 09 06 07 2A 85 03 02 02 1F 01 EncryptionParamSet encKey.SessionEncryptedKey.Ukm = new byte[] { 0x6A, 0x0F, 0x44, 0x24, 0xB6, 0xCB, 0x8B, 0x7C }; encKey.SessionEncryptedKey.EncryptedKey = new byte[] { 0x91, 0x8B, 0xD1, 0x55, 0x2D, 0x7D, 0x07, 0x67, 0x6F, 0x03, 0x42, 0x8E, 0xDC, 0xBE, 0xD0, 0x9B, 0x84, 0xBA, 0x8E, 0x04, 0xE7, 0xFA, 0x3A, 0x2A, 0x9B, 0x2C, 0xF6, 0xF1, 0x71, 0x86, 0x3D, 0xF6 }; encKey.SessionEncryptedKey.Mac = new byte[] { 0x4E, 0x32, 0x52, 0x65 }; encKey.SessionEncryptedKey.EncryptionParamSet = "1.2.643.2.2.31.1"; encKey.TransportParameters.DigestParamSet = "1.2.643.7.1.1.2.2"; encKey.TransportParameters.PublicKey = new byte[] { 0x8B, 0xFF, 0x19, 0x01, 0x0B, 0xCF, 0xBB, 0xC9, 0x03, 0x59, 0x58, 0xD0, 0x6F, 0x24, 0xC1, 0x3C, 0x5D, 0x1F, 0xAC, 0x9B, 0xF8, 0xF7, 0x24, 0x7B, 0x48, 0x4E, 0x39, 0x2E, 0x9A, 0x42, 0xB6, 0x66, 0x60, 0xCA, 0xD8, 0x0E, 0x62, 0x7E, 0x22, 0x15, 0xCC, 0xC9, 0xE5, 0xA6, 0x2E, 0x58, 0xFF, 0x9B, 0x1D, 0xFB, 0xEA, 0x7B, 0x5E, 0x42, 0xB5, 0xFD, 0x51, 0x97, 0xBD, 0xD9, 0x6E, 0x24, 0x16, 0xAC }; encKey.TransportParameters.PublicKeyParamSet = "1.2.643.2.2.36.0"; Gost28147 key = (Gost28147)Deformatter.DecryptKeyExchange(encKey); key.IV = sessionKeyIV.Split(' ').Select(c => Convert.ToByte(c, 16)).ToArray(); //byte[] encBytes = Enumerable.Range(0, dataEncrypted.Length) // .Where(x => x % 2 == 0) // .Select(x => Convert.ToByte(dataEncrypted.Substring(x, 2), 16)) // .ToArray(); byte[] encBytes = Convert.FromBase64String(dataEncrypted); byte[] targetBytes = new byte[1024]; int currentPosition = 0; CPCryptoAPITransform cryptoTransform = (CPCryptoAPITransform)key.CreateDecryptor(); int inputBlockSize = cryptoTransform.InputBlockSize; int sourceByteLength = encBytes.Length; try { int numBytesRead = 0; while (sourceByteLength - currentPosition >= inputBlockSize) { numBytesRead = cryptoTransform.TransformBlock( encBytes, currentPosition, inputBlockSize, targetBytes, currentPosition); currentPosition += numBytesRead; } byte[] finalBytes = cryptoTransform.TransformFinalBlock( encBytes, currentPosition, sourceByteLength - currentPosition); finalBytes.CopyTo(targetBytes, currentPosition); } catch (Exception ex) { Console.WriteLine("Caught unexpected exception:" + ex.ToString()); } byte[] retVal = TrimArray(targetBytes); return(retVal); }