Подпись ИЭМК с помощью VipNet CSP: различия между версиями
Перейти к навигации
Перейти к поиску
Dmitriy (обсуждение | вклад) |
Dmitriy (обсуждение | вклад) |
||
Строка 49: | Строка 49: | ||
} | } | ||
</pre> | </pre> | ||
− | Далее. Для подписи требуется библиотека GostCryptography. Заливаем через nuget, подключаем. | + | Далее. Для подписи требуется библиотека GostCryptography (https://github.com/AlexMAS/GostCryptography). Заливаем через nuget, подключаем. |
+ | |||
<pre> | <pre> | ||
using GostCryptography; | using GostCryptography; | ||
Строка 150: | Строка 151: | ||
} | } | ||
</pre> | </pre> | ||
+ | |||
+ | Вызов класса | ||
+ | <pre>SignSmevRequestVip(args[0], args[1], CertItog);</pre> |
Версия 14:44, 20 октября 2016
Поиск нужного сертификата. Ищем по конкретному СНИЛСу и действующий на текущую дату.
X509Certificate2 CertItog = find_certificate_();
public static X509Certificate2 find_certificate_() { X509Store store = new X509Store("MY", StoreLocation.CurrentUser); store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly); X509Certificate2 cert = new X509Certificate2(); X509Certificate2Collection collection = (X509Certificate2Collection)store.Certificates; X509Certificate2Collection fcollection = (X509Certificate2Collection)collection.Find(X509FindType.FindByTimeValid, DateTime.Now, false); string str_SN = ""; foreach (X509Certificate2 x509 in fcollection) { try { if (x509.Subject.ToUpper().Contains("SNILS") || x509.Subject.ToUpper().Contains("СНИЛС")) { str_SN = x509.Subject.Substring(x509.Subject.IndexOf("SNILS") + 6, 11); int n; if (!int.TryParse(str_SN.Substring(0, 10), out n)) { str_SN = x509.Subject.Substring(x509.Subject.ToUpper().IndexOf("СНИЛС") + 6, 11); if (!int.TryParse(str_SN.Substring(0, 10), out n)) { continue; // System.Windows.Forms.MessageBox.Show("Снилс в сертификате не найден или пустой"); } } if (String.CompareOrdinal(str_SN, "NNNNNNNNNNNNN") == 0) { cert = x509; // Console.WriteLine(cert.Subject); Console.WriteLine(str_SN); // Console.ReadKey(); break; } } x509.Reset(); } catch (CryptographicException) { Console.WriteLine("Information could not be written out for this certificate."); } } store.Close(); return cert; }
Далее. Для подписи требуется библиотека GostCryptography (https://github.com/AlexMAS/GostCryptography). Заливаем через nuget, подключаем.
using GostCryptography; using GostCryptography.Cryptography; using GostCryptography.Xml;
Для СМЭВ пользуем доп. класс Добавляем константы
private const string WsSecurityExtNamespace = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"; private const string WsSecurityUtilityNamespace = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd";
private static XmlElement GetSmevIdElement(XmlDocument document, string idValue) { var namespaceManager = new XmlNamespaceManager(document.NameTable); namespaceManager.AddNamespace("wsu", WsSecurityUtilityNamespace); return document.SelectSingleNode("//*[@wsu:Id='" + idValue + "']", namespaceManager) as XmlElement; }
И, собственно алгоритм подписи/ На выходе формируется отдельный файл.
private static XmlDocument SignSmevRequestVip(string FileName, string SignedFileName, X509Certificate2 signingCertificate) { XmlDocument smevRequest = new XmlDocument(); smevRequest.PreserveWhitespace = true; smevRequest.Load(new XmlTextReader(FileName)); // Создание подписчика XML-документа var signedXml = new GostSignedXml(smevRequest) { GetIdElementHandler = GetSmevIdElement }; // Установка ключа для создания подписи signedXml.SetSigningCertificate(signingCertificate); // Ссылка на узел, который нужно подписать, с указанием алгоритма хэширования ГОСТ Р 34.11-94 (в соответствии с методическими рекомендациями СМЭВ) var dataReference = new Reference { Uri = "#BODY", DigestMethod = GostSignedXml.XmlDsigGost3411ObsoleteUrl }; // Метод преобразования, применяемый к данным перед их подписью (в соответствии с методическими рекомендациями СМЭВ) var dataTransform = new XmlDsigExcC14NTransform(); dataReference.AddTransform(dataTransform); // Установка ссылки на узел signedXml.AddReference(dataReference); //reference #wsa300 var dataReferenceWSA300 = new Reference { Uri = "#WSA-300", DigestMethod = GostSignedXml.XmlDsigGost3411ObsoleteUrl }; var dataTransformWSA300 = new XmlDsigExcC14NTransform(); dataReferenceWSA300.AddTransform(dataTransformWSA300); signedXml.AddReference(dataReferenceWSA300); //reference #WSA-301 var dataReferenceWSA301 = new Reference { Uri = "#WSA-301", DigestMethod = GostSignedXml.XmlDsigGost3411ObsoleteUrl }; var dataTransformWSA301 = new XmlDsigExcC14NTransform(); dataReferenceWSA301.AddTransform(dataTransformWSA301); signedXml.AddReference(dataReferenceWSA301); //reference #WSA-302 var dataReferenceWSA302 = new Reference { Uri = "#WSA-302", DigestMethod = GostSignedXml.XmlDsigGost3411ObsoleteUrl }; var dataTransformWSA302 = new XmlDsigExcC14NTransform(); dataReferenceWSA302.AddTransform(dataTransformWSA302); signedXml.AddReference(dataReferenceWSA302); //reference #WSA-303 var dataReferenceWSA303 = new Reference { Uri = "#WSA-303", DigestMethod = GostSignedXml.XmlDsigGost3411ObsoleteUrl }; var dataTransformWSA303 = new XmlDsigExcC14NTransform(); dataReferenceWSA303.AddTransform(dataTransformWSA303); signedXml.AddReference(dataReferenceWSA303); //reference #TRHEAD var dataReferenceTRHEAD = new Reference { Uri = "#TRHEAD", DigestMethod = GostSignedXml.XmlDsigGost3411ObsoleteUrl }; var dataTransformTRHEAD = new XmlDsigExcC14NTransform(); dataReferenceTRHEAD.AddTransform(dataTransformTRHEAD); signedXml.AddReference(dataReferenceTRHEAD); //reference #CertId var dataReferenceCertId = new Reference { Uri = "#CertId", DigestMethod = GostSignedXml.XmlDsigGost3411ObsoleteUrl }; var dataTransformCertId = new XmlDsigExcC14NTransform(); dataReferenceCertId.AddTransform(dataTransformCertId); signedXml.AddReference(dataReferenceCertId); // Установка алгоритма нормализации узла SignedInfo (в соответствии с методическими рекомендациями СМЭВ) signedXml.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigExcC14NTransformUrl; // Установка алгоритма подписи ГОСТ Р 34.10-2001 (в соответствии с методическими рекомендациями СМЭВ) signedXml.SignedInfo.SignatureMethod = GostSignedXml.XmlDsigGost3410ObsoleteUrl; // Вычисление подписи signedXml.ComputeSignature(); // Получение XML-представления подписи var signatureXml = signedXml.GetXml(); // Добавление подписи в исходный документ smevRequest.GetElementsByTagName("Signature")[0].PrependChild(smevRequest.ImportNode(signatureXml.GetElementsByTagName("SignatureValue")[0], true)); smevRequest.GetElementsByTagName("Signature")[0].PrependChild(smevRequest.ImportNode(signatureXml.GetElementsByTagName("SignedInfo")[0], true)); smevRequest.GetElementsByTagName("wsse:BinarySecurityToken")[0].InnerText = Convert.ToBase64String(signingCertificate.RawData); using (XmlTextWriter xmltw = new XmlTextWriter(SignedFileName, new UTF8Encoding(false))) { smevRequest.WriteTo(xmltw); } return smevRequest; }
Вызов класса
SignSmevRequestVip(args[0], args[1], CertItog);