/// <summary> /// Дешифровка марканта с помошью ключа согласования /// </summary> /// <param name="markant">Маркант для дешифровки</param> /// <param name="providerInitData">Информация для инициализации контейнера криптопровайдера c закрытым ключом получателя</param> /// <returns>Дешифрованный сессионный ключ</returns> public static Gost28147 DecryptMarkantWithKeyAgree(Markant markant, ProviderInitData providerInitData) { //Готовим параметры контейнера CspParameters decrypt_cspParameters = new CspParameters { ProviderType = (int)providerInitData.ProviderType, Flags = CspProviderFlags.NoPrompt, KeyPassword = providerInitData.ProviderPassword, KeyContainerName = providerInitData.ProviderContainerName }; //Открываем контейнер Gost3410_2012_256CryptoServiceProvider decrypt_gost3410 = new Gost3410_2012_256CryptoServiceProvider(decrypt_cspParameters); // Читаем открытый ключ Gost3410Parameters decrypt_gost3410PublicKeyParameters = (Gost3410Parameters)Helper.ByteArrayToObject(markant.PublicKey); // Создаем agree ключ GostSharedSecretAlgorithm agree = decrypt_gost3410.CreateAgree(decrypt_gost3410PublicKeyParameters); // Расшифровываем симметричный ключ на agree Gost28147 decrypt_gost28147 = (Gost28147)agree.Unwrap(markant.SessionKey, GostKeyWrapMethod.CryptoProKeyWrap); decrypt_gost28147.IV = markant.IV; if (decrypt_gost28147 == null) { throw new Exception("Invalid decrypted session key"); } // Устанавливаем синхропосылку. decrypt_gost28147.IV = markant.IV; return(decrypt_gost28147); }
/// <summary> /// Дешифровка марканта с помошью KeyExchangeFormatter /// </summary> /// <param name="markant">Маркант для дешифровки</param> /// <param name="providerInitData">Информация для инициализации контейнера криптопровайдера c закрытым ключом получателя</param> /// <returns>Дешифрованный сессионный ключ</returns> public static Gost28147 DecryptMarkantWithKeyExchangeFormatter(Markant markant, ProviderInitData providerInitData) { //Готовим параметры контейнера CspParameters decrypt_cspParameters = new CspParameters { ProviderType = (int)providerInitData.ProviderType, Flags = CspProviderFlags.NoPrompt, KeyPassword = providerInitData.ProviderPassword, KeyContainerName = providerInitData.ProviderContainerName }; //Открываем контейнер Gost3410_2012_256CryptoServiceProvider decrypt_gost3410 = new Gost3410_2012_256CryptoServiceProvider(decrypt_cspParameters); // Деформаттер для ключей, зашифрованных на ассиметричном ключе получателя. Gost2012_256KeyExchangeDeformatter decrypt_gostKeyExchangeDeformatter = new Gost2012_256KeyExchangeDeformatter(decrypt_gost3410); // Получаем ГОСТ-овый ключ из GostKeyTransport. GostKeyTransport gostKeyTransport = new GostKeyTransport(); gostKeyTransport.Decode(markant.SessionKey); Gost28147 decrypt_gost28147 = (Gost28147)decrypt_gostKeyExchangeDeformatter.DecryptKeyExchange(gostKeyTransport); if (decrypt_gost28147 == null) { throw new Exception("Invalid decrypted session key"); } // Устанавливаем синхропосылку. decrypt_gost28147.IV = markant.IV; return(decrypt_gost28147); }
public void CreateKeyRoundtripBlob() { const int KeySize = 512; byte[] blob; using (var gost = GetGostProvider()) { CspKeyContainerInfo containerInfo = gost.CspKeyContainerInfo; Assert.Equal(Gost2012_256ProvType, containerInfo.ProviderType); Assert.Equal(KeySize, gost.KeySize); blob = gost.ExportCspBlob(false); } using (var gost = new Gost3410_2012_256CryptoServiceProvider()) { gost.ImportCspBlob(blob); CspKeyContainerInfo containerInfo = gost.CspKeyContainerInfo; // The provider information is not persisted in the blob Assert.Equal(Gost2012_256ProvType, containerInfo.ProviderType); Assert.Equal(KeySize, gost.KeySize); } }
public byte[] Sign(byte[] data, int certIndex) { try { if (hash == null) { throw new NullReferenceException("Compute hash first"); } CspParameters cp = new CspParameters(); var privateKey = ClientCertificates[certIndex].PrivateKey as Gost3410_2012_256CryptoServiceProvider; var uniqueKeyContainerName = privateKey.CspKeyContainerInfo.UniqueKeyContainerName; cp.KeyContainerName = uniqueKeyContainerName; cp.ProviderType = 75; cp.ProviderName = null; Gost3410_2012_256 gkey = new Gost3410_2012_256CryptoServiceProvider(cp); Gost3410_2012_256CryptoServiceProvider srcContainer = new Gost3410_2012_256CryptoServiceProvider(cp); Gost3410Parameters srcPublicKeyParameters = srcContainer.ExportParameters(false); if (srcContainer == null) { throw new Exception("У сертификата нет приватного ключа"); } signature = srcContainer.CreateSignature(hasher.Hash); sCert = ClientCertificates[certIndex].Export(X509ContentType.Cert); sTime = DateTime.Now; return(Asn1Formatter.CreateSignature(signature, sCert, sTime, data)); } catch (CryptographicException ex) { Console.WriteLine(ex.Message); return(null); } }
// Шифрование тестового файла. 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); } } } } }
// Расшифрование тестового файла. static void DecryptTestFile(Gost3410_2012_256CryptoServiceProvider privateKey, string fileId = "2012_256") { // Открываем зашифрованный файл. using (FileStream ifs = new FileStream(string.Format(EncryptedFileName, fileId), FileMode.Open, FileAccess.Read)) { // Читаем зашифрованный симметричный ключ. BinaryReader br = new BinaryReader(ifs); byte[] cek; int cekLength = br.ReadInt32(); cek = br.ReadBytes(cekLength); // Читаем синхропосылку byte[] iv; int ivLength = br.ReadInt32(); iv = br.ReadBytes(ivLength); // Читаем открытый ключ. BinaryFormatter formatter = new BinaryFormatter(); Gost3410Parameters srcPublicKeyParameters = (Gost3410Parameters)formatter.Deserialize(ifs); // Создаем agree ключ GostSharedSecretAlgorithm agree = privateKey.CreateAgree( srcPublicKeyParameters); // Расшифровываем симметричный ключ на agree SymmetricAlgorithm symmetric = agree.Unwrap(cek, GostKeyWrapMethod.CryptoPro12KeyWrap); symmetric.IV = iv; // Создаем поток разшифрования. ICryptoTransform transform = symmetric.CreateDecryptor(); // Создаем поток разшифрования из файла. using (CryptoStream cs = new CryptoStream(ifs, transform, CryptoStreamMode.Read)) { // Открываем расшифрованный файл using (FileStream ofs = new FileStream(string.Format(DecryptedFileName, fileId), FileMode.Create)) { byte[] data = new byte[4096]; // и переписываем содержимое в выходной поток. int length = cs.Read(data, 0, data.Length); while (length > 0) { ofs.Write(data, 0, length); length = cs.Read(data, 0, data.Length); } } } } }
/// <summary> /// Создает маркант с помошью ключа согласования /// </summary> /// <param name="gost28147">Сессионный ключ</param> /// <param name="certFileName">Путь к файлу сертификата получателя</param> /// <param name="providerInitData">Информация для инициализации контейнера криптопровайдера c закрытым ключом отправителя</param> /// <returns>Сгенерированный маркант</returns> public static Markant CreateMarkantWithKeyAgree(Gost28147 gost28147, string certFileName, ProviderInitData providerInitData) { // Разбираем сертификат получателя X509Certificate2 cert = new X509Certificate2(certFileName); if (!(cert.PublicKey.Key is Gost3410_2012_256 gost3410)) { throw new CryptographicException("Not a GOST certificate"); } //Готовим параметры контейнера CspParameters cspParameters = new CspParameters { ProviderType = (int)providerInitData.ProviderType, Flags = CspProviderFlags.NoPrompt, KeyPassword = providerInitData.ProviderPassword, KeyContainerName = providerInitData.ProviderContainerName }; //Открываем контейнер Gost3410_2012_256CryptoServiceProvider encrypt_gost3410 = new Gost3410_2012_256CryptoServiceProvider(cspParameters); Gost3410Parameters encrypt_gost3410PublicKeyParameters = encrypt_gost3410.ExportParameters(false); // Создаем agree ключ GostSharedSecretAlgorithm agree = encrypt_gost3410.CreateAgree(gost3410.ExportParameters(false)); // Зашифровываем симметричный ключ на agree ключе. byte[] wrappedKey = agree.Wrap(gost28147, GostKeyWrapMethod.CryptoProKeyWrap); //Формируем маркант Markant m = new Markant { Version = 2, SessionKey = wrappedKey, IV = gost28147.IV, PublicKey = Helper.ObjectToByteArray(encrypt_gost3410PublicKeyParameters) }; return(m); }
/// <summary> /// Создать сертификат ГОСТ 34.10.2012 256 /// </summary> private static void MakeMeCert() { using (var parent = new Gost3410_2012_256CryptoServiceProvider()) { var parentReq = new CertificateRequest( "CN=Experimental Issuing Authority", parent, HashAlgorithmName.Gost3411_2012_256); parentReq.CertificateExtensions.Add( new X509BasicConstraintsExtension(true, false, 0, true)); parentReq.CertificateExtensions.Add( new X509SubjectKeyIdentifierExtension(parentReq.PublicKey, false)); using (var parentCert = parentReq.CreateSelfSigned( DateTimeOffset.UtcNow.AddDays(-45), DateTimeOffset.UtcNow.AddDays(365))) { byte[] certData = parentCert.Export(X509ContentType.Pfx, "1"); File.WriteAllBytes(@"MyCert.pfx", certData); } } }
public void Get_ContainerNames() { uint pcbData = 0; uint dwFlags = CRYPT_FIRST; IntPtr hProv = IntPtr.Zero; bool gotcsp = CryptAcquireContext(ref hProv, null, "Crypto-Pro GOST R 34.10-2001 Cryptographic Service Provider", PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CSPKEYTYPE); StringBuilder sb = null; CryptGetProvParam(hProv, PP_ENUMCONTAINERS, sb, ref pcbData, dwFlags); sb = new StringBuilder((int)(2 * pcbData)); dwFlags = CRYPT_FIRST; DateTime dt = DateTime.Now; string curDate = dt.ToShortDateString(); X509Certificate2 CurrentCert; String[] CertStorage; while (CryptGetProvParam(hProv, PP_ENUMCONTAINERS, sb, ref pcbData, dwFlags)) { dwFlags = 0; cspParameters.KeyContainerName = sb.ToString(); cspParameters.Flags = CspProviderFlags.NoPrompt; try { CryptoServiceProvider2001 = new Gost3410CryptoServiceProvider(cspParameters); CurrentCert = CryptoServiceProvider2001.ContainerCertificate; CertStorage = CryptoServiceProvider2001.CspKeyContainerInfo.UniqueKeyContainerName.Split(new char[] { '\\' }, StringSplitOptions.RemoveEmptyEntries); } catch (Exception Ex) { if (Environment.OSVersion.Version.Major < 6) { return; } if (Convert.ToInt32(CSPVersion()[0].ToString()) < 4) { return; } CryptoServiceProvider2012 = new Gost3410_2012_256CryptoServiceProvider(cspParameters); CurrentCert = CryptoServiceProvider2012.ContainerCertificate; CertStorage = CryptoServiceProvider2012.CspKeyContainerInfo.UniqueKeyContainerName.Split(new char[] { '\\' }, StringSplitOptions.RemoveEmptyEntries); } try { if (CurrentCert != null) { Invoke(new Action(() => label1.Text = "Поиск в контейнере: " + CertStorage[1])); if (CurrentCert.NotAfter < DateTime.Now) { Invoke(new Action(() => label1.Text = "Истек срок действия: " + CurrentCert.SerialNumber + " (" + CurrentCert.NotAfter + ")")); } else { string GetNameInfo = CurrentCert.GetNameInfo(X509NameType.SimpleName, true); if (GetNameInfo.Contains("Link-Service") || GetNameInfo.Contains("Линк-сервис") || CertStorage[0].Contains("LINK")) { X509Store CertificationStore = new X509Store(StoreName.My, StoreLocation.CurrentUser); CertificationStore.Open(OpenFlags.ReadWrite); X509CertificateParser parser = new X509CertificateParser(); byte[] rawdata = CurrentCert.RawData; Org.BouncyCastle.X509.X509Certificate cert = parser.ReadCertificate(rawdata); DerSequence subject = cert.SubjectDN.ToAsn1Object() as DerSequence; foreach (Asn1Encodable setItem in subject) { DerSet subSet = setItem as DerSet; if (subSet == null) { continue; } DerSequence subSeq = subSet[0] as DerSequence; foreach (Asn1Encodable subSeqItem in subSeq) { DerObjectIdentifier oid = subSeqItem as DerObjectIdentifier; if (oid == null) { continue; } string value = subSeq[1].ToString(); if (oid.Id.Equals("2.5.4.3")) { CN = value; } } } if (!CertStorage[0].Contains("ePass")) // ePass break; Equals { if (CertStorage[0] != "REGISTRY") { InstallCertificate(CurrentCert); } else { InstallCertificate(CurrentCert); } } CertificationStore.Close(); // CryptoServiceProvider.Clear(); } else { Invoke(new Action(() => label1.Text = "Сертификат: " + CurrentCert.SerialNumber + " (недоступен)")); } } } } catch (Exception ex) { //LogWrite(ex); } } if (hProv != IntPtr.Zero) { CryptReleaseContext(hProv, 0); } }
public AsymmetricAlgorithm DecodePublicKey(Oid oid, byte[] encodedKeyValue, byte[] encodedParameters, ICertificatePal certificatePal) { if (oid.Value == Oids.EcPublicKey && certificatePal != null) { return(DecodeECDsaPublicKey((CertificatePal)certificatePal)); } int algId = Interop.Crypt32.FindOidInfo(CryptOidInfoKeyType.CRYPT_OID_INFO_OID_KEY, oid.Value, OidGroup.PublicKeyAlgorithm, fallBackToAllGroups: true).AlgId; switch (algId) { case AlgId.CALG_RSA_KEYX: case AlgId.CALG_RSA_SIGN: { byte[] keyBlob = DecodeKeyBlob(CryptDecodeObjectStructType.CNG_RSA_PUBLIC_KEY_BLOB, encodedKeyValue); CngKey cngKey = CngKey.Import(keyBlob, CngKeyBlobFormat.GenericPublicBlob); return(new RSACng(cngKey)); } //begin: gost case AlgId.CALG_GOST3410: { var cspObject = new GostKeyExchangeParameters(); cspObject.DecodeParameters(encodedParameters); cspObject.DecodePublicKey(encodedKeyValue, algId); var cspBlobData = GostKeyExchangeParameters.EncodePublicBlob(cspObject, algId); Gost3410CryptoServiceProvider gost_sp = new Gost3410CryptoServiceProvider(); gost_sp.ImportCspBlob(cspBlobData); return(gost_sp); } case AlgId.CALG_GOST3410_2012_256: { var cspObject = new GostKeyExchangeParameters(); cspObject.DecodeParameters(encodedParameters); cspObject.DecodePublicKey(encodedKeyValue, algId); var cspBlobData = GostKeyExchangeParameters.EncodePublicBlob(cspObject, algId); Gost3410_2012_256CryptoServiceProvider gost_sp = new Gost3410_2012_256CryptoServiceProvider(); gost_sp.ImportCspBlob(cspBlobData); return(gost_sp); } case AlgId.CALG_GOST3410_2012_512: { var cspObject = new GostKeyExchangeParameters(); cspObject.DecodeParameters(encodedParameters); cspObject.DecodePublicKey(encodedKeyValue, algId); var cspBlobData = GostKeyExchangeParameters.EncodePublicBlob(cspObject, algId); Gost3410_2012_512CryptoServiceProvider gost_sp = new Gost3410_2012_512CryptoServiceProvider(); gost_sp.ImportCspBlob(cspBlobData); return(gost_sp); } //end: gost case AlgId.CALG_DSS_SIGN: { byte[] keyBlob = ConstructDSSPublicKeyCspBlob(encodedKeyValue, encodedParameters); DSACryptoServiceProvider dsa = new DSACryptoServiceProvider(); dsa.ImportCspBlob(keyBlob); return(dsa); } default: throw new NotSupportedException(SR.NotSupported_KeyAlgorithm); } }
/// <summary> /// Вспомогательный прокси метод для тестирования шифрования на асимметричном ключе /// </summary> /// <param name="gostKey"></param> private void Encrypt(AsymmetricAlgorithm gostKey) { if (gostKey is Gost3410 gost3410) { Console.WriteLine("Секретный ключ получен."); // и получаем открытый ключ. Gost3410Parameters publicKey = gost3410.ExportParameters(false); Console.WriteLine("На стороне отправителя..."); // Полученный открытый ключ передаем отправителю сообщения. using (Gost3410CryptoServiceProvider pubKey = new Gost3410CryptoServiceProvider()) { pubKey.ImportParameters(publicKey); Console.WriteLine("Открытый ключ получен."); // Создаем Xml файл для зашифрования. CreateSomeXml("ato_encrypt_2001.xml"); Console.WriteLine("Создан новый XML файл."); // Зашифровываем узел, заданный xpath выражением, XML документа // ato_encrypt.xml в документ a_encrypted.xml // Для зашифрования используется открытый ключ pubKey. Encrypt("ato_encrypt_2001.xml", "a_encrypted_2001.xml", "//SomeNode[@ToEncrypt='true']", "EncryptedElement1", pubKey, "KeyAlias"); Console.WriteLine("Узел XML файла зашифрован."); Console.WriteLine("На стороне получателя..."); Decrypt("a_encrypted_2001.xml", "a_decrypted_2001.xml", gost3410, "KeyAlias"); } } else if (gostKey is Gost3410_2012_256 gost3410_2012_256) { Console.WriteLine("Секретный ключ получен."); // и получаем открытый ключ. Gost3410Parameters publicKey = gost3410_2012_256.ExportParameters(false); Console.WriteLine("На стороне отправителя..."); // Полученный открытый ключ передаем отправителю сообщения. using (Gost3410_2012_256CryptoServiceProvider pubKey = new Gost3410_2012_256CryptoServiceProvider()) { pubKey.ImportParameters(publicKey); Console.WriteLine("Открытый ключ получен."); // Создаем Xml файл для зашифрования. CreateSomeXml("ato_encrypt_2012_256.xml"); Console.WriteLine("Создан новый XML файл."); // Зашифровываем узел, заданный xpath выражением, XML документа // ato_encrypt.xml в документ a_encrypted.xml // Для зашифрования используется открытый ключ pubKey. Encrypt("ato_encrypt_2012_256.xml", "a_encrypted_2012_256.xml", "//SomeNode[@ToEncrypt='true']", "EncryptedElement1", pubKey, "KeyAlias"); Console.WriteLine("Узел XML файла зашифрован."); Console.WriteLine("На стороне получателя..."); Decrypt("a_encrypted_2012_256.xml", "a_decrypted_2012_256.xml", gost3410_2012_256, "KeyAlias"); } } else if (gostKey is Gost3410_2012_512 gost3410_2012_512) { Console.WriteLine("Секретный ключ получен."); // и получаем открытый ключ. Gost3410Parameters publicKey = gost3410_2012_512.ExportParameters(false); Console.WriteLine("На стороне отправителя..."); // Полученный открытый ключ передаем отправителю сообщения. using (Gost3410_2012_512CryptoServiceProvider pubKey = new Gost3410_2012_512CryptoServiceProvider()) { pubKey.ImportParameters(publicKey); Console.WriteLine("Открытый ключ получен."); // Создаем Xml файл для зашифрования. CreateSomeXml("ato_encrypt_2012_512.xml"); Console.WriteLine("Создан новый XML файл."); // Зашифровываем узел, заданный xpath выражением, XML документа // ato_encrypt.xml в документ a_encrypted.xml // Для зашифрования используется открытый ключ pubKey. Encrypt("ato_encrypt_2012_512.xml", "a_encrypted_2012_512.xml", "//SomeNode[@ToEncrypt='true']", "EncryptedElement1", pubKey, "KeyAlias"); Console.WriteLine("Узел XML файла зашифрован."); Console.WriteLine("На стороне получателя..."); Decrypt("a_encrypted_2012_512.xml", "a_decrypted_2012_512bui.xml", gost3410_2012_512, "KeyAlias"); } } else { throw new NotSupportedException(); } Console.WriteLine("XML документ расшифрован."); }
public void Constructor() { var gost = new Gost3410_2012_256CryptoServiceProvider(); Assert.NotNull(gost); }
static void Main(string[] args) { try { socket.Init(); while (true) { byte[] data = socket.Recieve(); BERelement asn = BERelement.DecodePacket(data); int operation; if (asn.Items[0].Value.Length > 1) { operation = BitConverter.ToInt32(asn.Items[0].Value, 0); } else { operation = asn.Items[0].Value[0]; } switch (operation) { case (int)Cmd.certs: SendCertificatesList(); break; case (int)Cmd.cipher: SendCertificatesList(); data = socket.Recieve(); asn = BERelement.DecodePacket(data); string certName = Encoding.ASCII.GetString(asn.Items[0].Value); foreach (var cert in crypter.Certificates) { if (cert.FriendlyName == certName) { crypter.currentCertificate = cert; SendPublicKey(cert); break; } } data = socket.Recieve(); crypter.SetSymmetrKey(Asn1Formatter.GetSymAsn1(data)); crypter.IV = Asn1Formatter.GetIVAsn1(data); byte[] asn1Established = Asn1Formatter.SetCertASN1(Encoding.ASCII.GetBytes("ESTABLISHED")); socket.Send(asn1Established); data = socket.Recieve(); String text = Encoding.ASCII.GetString(crypter.Decrypt(data)); Console.WriteLine("Recieved data from client: " + text); break; case (int)Cmd.sign: asn1Established = Asn1Formatter.SetCertASN1(Encoding.ASCII.GetBytes("ESTABLISHED")); socket.Send(asn1Established); data = socket.Recieve(); asn = BERelement.DecodePacket(data); try { if (asn.Items[0].Value.Length > 1) { operation = BitConverter.ToInt32(asn.Items[0].Value, 0); } else { operation = asn.Items[0].Value[0]; } if (operation == (int)Cmd.error) { Console.WriteLine("Error!"); continue; } } catch (NotSupportedException) { Console.WriteLine("Signed message came!"); } BERelement mSeq = BERelement.DecodePacket(data); BERelement sSeq = mSeq.Items[0]; BERelement fSeq = mSeq.Items[1]; var signature = sSeq.Items[0].Value; var certS = new X509Certificate2(sSeq.Items[1].Value); var time = DateTime.FromBinary(BitConverter.ToInt64(sSeq.Items[2].Value, 0)); var sData = fSeq.Items[0].Value; Gost3410_2012_256CryptoServiceProvider sGost = (Gost3410_2012_256CryptoServiceProvider)certS.PublicKey.Key; Gost3411CryptoServiceProvider hGost = new Gost3411CryptoServiceProvider(); bool correct = sGost.VerifySignature(hGost.ComputeHash(sData), signature); Console.WriteLine($"Friendly name: {certS.FriendlyName}"); Console.WriteLine(certS + "\n"); Console.WriteLine("Signature time..."); Console.WriteLine(time + "\n"); Console.WriteLine("Correct signature?..."); Console.WriteLine(correct + "\n"); Console.WriteLine("Data:"); Console.WriteLine(Encoding.ASCII.GetString(sData) + "\n"); break; default: break; } } } catch (Exception ex) { Console.WriteLine(ex.Message); } }
// begin: gost public unsafe void SetCspPrivateKey(AsymmetricAlgorithm key) { if (key == null) { return; } CspKeyContainerInfo keyContainerInfo; switch (key.SignatureAlgorithm) { case GostConstants.XmlSignatureAlgorithm2001: { Gost3410CryptoServiceProvider asymmetricAlgorithm = key as Gost3410CryptoServiceProvider; keyContainerInfo = asymmetricAlgorithm.CspKeyContainerInfo; break; } case GostConstants.XmlSignatureAlgorithm2012_256: { Gost3410_2012_256CryptoServiceProvider asymmetricAlgorithm = key as Gost3410_2012_256CryptoServiceProvider; keyContainerInfo = asymmetricAlgorithm.CspKeyContainerInfo; break; } case GostConstants.XmlSignatureAlgorithm2012_512: { Gost3410_2012_512CryptoServiceProvider asymmetricAlgorithm = key as Gost3410_2012_512CryptoServiceProvider; keyContainerInfo = asymmetricAlgorithm.CspKeyContainerInfo; break; } case "RSA": { RSACryptoServiceProvider asymmetricAlgorithm = key as RSACryptoServiceProvider; keyContainerInfo = asymmetricAlgorithm.CspKeyContainerInfo; break; } case "DSA": { DSACryptoServiceProvider asymmetricAlgorithm = key as DSACryptoServiceProvider; keyContainerInfo = asymmetricAlgorithm.CspKeyContainerInfo; break; } default: { throw new PlatformNotSupportedException(); } } SafeLocalAllocHandle ptr = SafeLocalAllocHandle.InvalidHandle; fixed(char *keyContainerName = keyContainerInfo.KeyContainerName) fixed(char *providerName = keyContainerInfo.ProviderName) { CRYPT_KEY_PROV_INFO keyProvInfo = new CRYPT_KEY_PROV_INFO(); keyProvInfo.pwszContainerName = keyContainerName; keyProvInfo.pwszProvName = providerName; keyProvInfo.dwProvType = keyContainerInfo.ProviderType; keyProvInfo.dwFlags = keyContainerInfo.MachineKeyStore ? CryptAcquireContextFlags.CRYPT_MACHINE_KEYSET : CryptAcquireContextFlags.None; keyProvInfo.cProvParam = 0; keyProvInfo.rgProvParam = IntPtr.Zero; keyProvInfo.dwKeySpec = (int)keyContainerInfo.KeyNumber; if (!Interop.crypt32.CertSetCertificateContextProperty( _certContext, CertContextPropId.CERT_KEY_PROV_INFO_PROP_ID, CertSetPropertyFlags.None, &keyProvInfo)) { throw Marshal.GetLastWin32Error().ToCryptographicException(); } } }