private static XmlElement Smev3Signed(Stream message, string id) { var document = new XmlDocument(); document.PreserveWhitespace = false; document.Load(message); var signedXml = new SmevSignedXml(document); using (var key = GostCryptoConfig.CreateGost3410AsymmetricAlgorithm()) { var reference = new Reference(); reference.Uri = "#" + id; reference.AddTransform(new XmlDsigExcC14NTransform()); reference.AddTransform(new XmlDsigSmevTransform()); signedXml.SigningKey = key; signedXml.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigExcC14NTransformUrl; if (GostCryptoConfig.ProviderType == ProviderTypes.CryptoPro256) { signedXml.SignedInfo.SignatureMethod = SignedXml.XmlDsigGost3410_2012_256Url; reference.DigestMethod = SignedXml.XmlDsigGost3411_2012_256Url; } else if (GostCryptoConfig.ProviderType == ProviderTypes.CryptoPro512) { signedXml.SignedInfo.SignatureMethod = SignedXml.XmlDsigGost3410_2012_512Url; reference.DigestMethod = SignedXml.XmlDsigGost3411_2012_512Url; } else { signedXml.SignedInfo.SignatureMethod = SignedXml.XmlDsigGost3410UrlObsolete; reference.DigestMethod = SignedXml.XmlDsigGost3411UrlObsolete; } signedXml.AddReference(reference); var keyInfo = new KeyInfo(); keyInfo.AddClause(new KeyInfoX509Data(key.ContainerCertificate)); signedXml.KeyInfo = keyInfo; signedXml.ComputeSignature("ds"); } var smevSign = signedXml.GetXml("ds"); return(smevSign); }
private static XmlDocument SignSmevRequest(XmlDocument smevRequest, Gost3410AsymmetricAlgorithm signingCertificate) { // Создание подписчика XML-документа var signedXml = new SmevSignedXml(smevRequest); // { GetIdElementHandler = GetSmevIdElement }; // Установка ключа для создания подписи signedXml.SigningKey = signingCertificate; // Ссылка на узел, который нужно подписать, с указанием алгоритма хэширования ГОСТ Р 34.11-94 (в соответствии с методическими рекомендациями СМЭВ) var dataReference = new Reference { Uri = "#body", DigestMethod = SignedXml.XmlDsigGost3411UrlObsolete }; // Метод преобразования, применяемый к данным перед их подписью (в соответствии с методическими рекомендациями СМЭВ) var dataTransform = new XmlDsigExcC14NTransform(); dataReference.AddTransform(dataTransform); // Установка ссылки на узел signedXml.AddReference(dataReference); // Установка алгоритма нормализации узла SignedInfo (в соответствии с методическими рекомендациями СМЭВ) signedXml.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigExcC14NTransformUrl; // Установка алгоритма подписи ГОСТ Р 34.10-2001 (в соответствии с методическими рекомендациями СМЭВ) signedXml.SignedInfo.SignatureMethod = SignedXml.XmlDsigGost3410UrlObsolete; // Вычисление подписи signedXml.ComputeSignature(); // Получение XML-представления подписи var signatureXml = signedXml.GetXml(); // Добавление подписи в исходный документ smevRequest.GetElementsByTagName("ds:Signature")[0].PrependChild(smevRequest.ImportNode(signatureXml.GetElementsByTagName("SignatureValue")[0], true)); smevRequest.GetElementsByTagName("ds:Signature")[0].PrependChild(smevRequest.ImportNode(signatureXml.GetElementsByTagName("SignedInfo")[0], true)); smevRequest.GetElementsByTagName("wsse:BinarySecurityToken")[0].InnerText = Convert.ToBase64String(signingCertificate.ContainerCertificate.RawData); return(smevRequest); }
static void SignXmlFile(string FileName, string SignedFileName, X509Certificate2 Certificate) { // Создаем новый документ XML. XmlDocument doc = new XmlDocument(); // Читаем документ из файла. doc.Load(new XmlTextReader(FileName)); // Создаём объект SmevSignedXml - наследник класса SignedXml с перегруженным GetIdElement // для корректной обработки атрибута wsu:Id. SmevSignedXml signedXml = new SmevSignedXml(doc); // Задаём ключ подписи для документа SmevSignedXml. signedXml.SigningKey = Certificate.PrivateKey; // Создаем ссылку на подписываемый узел XML. В данном примере и в методических // рекомендациях СМЭВ подписываемый узел soapenv:Body помечен идентификатором "body". Reference reference = new Reference(); reference.Uri = "#body"; // Задаём алгоритм хэширования подписываемого узла - ГОСТ Р 34.11-94. Необходимо // использовать устаревший идентификатор данного алгоритма, т.к. именно такой // идентификатор используется в СМЭВ. #pragma warning disable 612 //warning CS0612: 'CryptoPro.Sharpei.Xml.CPSignedXml.XmlDsigGost3411UrlObsolete' is obsolete reference.DigestMethod = CryptoPro.Sharpei.Xml.CPSignedXml.XmlDsigGost3411UrlObsolete; #pragma warning restore 612 // Добавляем преобразование для приведения подписываемого узла к каноническому виду // по алгоритму http://www.w3.org/2001/10/xml-exc-c14n# в соответствии с методическими // рекомендациями СМЭВ. XmlDsigExcC14NTransform c14 = new XmlDsigExcC14NTransform(); reference.AddTransform(c14); // Добавляем ссылку на подписываемый узел. signedXml.AddReference(reference); // Задаём преобразование для приведения узла ds:SignedInfo к каноническому виду // по алгоритму http://www.w3.org/2001/10/xml-exc-c14n# в соответствии с методическими // рекомендациями СМЭВ. signedXml.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigExcC14NTransformUrl; // Задаём алгоритм подписи - ГОСТ Р 34.10-2001. Необходимо использовать устаревший // идентификатор данного алгоритма, т.к. именно такой идентификатор используется в // СМЭВ. #pragma warning disable 612 //warning CS0612: 'CryptoPro.Sharpei.Xml.CPSignedXml.XmlDsigGost3411UrlObsolete' is obsolete signedXml.SignedInfo.SignatureMethod = CryptoPro.Sharpei.Xml.CPSignedXml.XmlDsigGost3410UrlObsolete; #pragma warning restore 612 // Вычисляем подпись. signedXml.ComputeSignature(); // Получаем представление подписи в виде XML. XmlElement xmlDigitalSignature = signedXml.GetXml(); // Добавляем необходимые узлы подписи в исходный документ в заготовленное место. doc.GetElementsByTagName("ds:Signature")[0].PrependChild( doc.ImportNode(xmlDigitalSignature.GetElementsByTagName("SignatureValue")[0], true)); doc.GetElementsByTagName("ds:Signature")[0].PrependChild( doc.ImportNode(xmlDigitalSignature.GetElementsByTagName("SignedInfo")[0], true)); // Добавляем сертификат в исходный документ в заготовленный узел // wsse:BinarySecurityToken. doc.GetElementsByTagName("wsse:BinarySecurityToken")[0].InnerText = Convert.ToBase64String(Certificate.RawData); // Сохраняем подписанный документ в файл. using (XmlTextWriter xmltw = new XmlTextWriter(SignedFileName, new UTF8Encoding(false))) { doc.WriteTo(xmltw); } }