public string Sign( SignatureType mode, GostFlavor gostFlavor, string certificateThumbprint, string signThisPath, bool assignDs, string nodeToSign, bool ignoreExpiredCert = false, bool?isAddSigningTime = null) { XmlDocument xmlToSign = null; string stringToSign = null; byte[] bytesToSign = null; if ( assignDs && !new List <SignatureType>() { SignatureType.Smev3BaseDetached, SignatureType.Smev3SidebysideDetached, SignatureType.Smev3Ack }.Contains(mode)) { throw ExceptionFactory.GetException(ExceptionType.DsAssignmentNotSupported); } if (mode == SignatureType.Pkcs7String || mode == SignatureType.Pkcs7StringAllCert || mode == SignatureType.Pkcs7StringNoCert || mode == SignatureType.Rsa2048Sha256String || mode == SignatureType.RsaSha256String) { stringToSign = File.ReadAllText(signThisPath, Encoding.UTF8); } else if (mode == SignatureType.SigDetached || mode == SignatureType.SigDetachedAllCert || mode == SignatureType.SigDetachedNoCert) { bytesToSign = File.ReadAllBytes(signThisPath); } else { xmlToSign = new XmlDocument(); xmlToSign.Load(signThisPath); } return(Sign( mode, gostFlavor, certificateThumbprint, xmlToSign, assignDs, nodeToSign, ignoreExpiredCert, stringToSign, bytesToSign, isAddSigningTime)); }
private string Sign( SignatureType mode, GostFlavor gostFlavor, string certificateThumbprint, XmlDocument signThis, bool assignDs, string nodeToSign, bool ignoreExpiredCert = false, string stringToSign = null, byte[] bytesToSign = null, bool?isAddSigningTime = null) { ICertificateProcessor cp = new CertificateProcessor(); X509Certificate2 certificate = cp.SearchCertificateByThumbprint(certificateThumbprint); if (!certificate.HasPrivateKey) { throw ExceptionFactory.GetException(ExceptionType.PrivateKeyMissing, certificate.Subject); } if (!ignoreExpiredCert && cp.IsCertificateExpired(certificate)) { throw ExceptionFactory.GetException(ExceptionType.CertExpired, certificate.Thumbprint); } return(Sign(mode, gostFlavor, certificate, signThis, assignDs, nodeToSign, stringToSign, bytesToSign, isAddSigningTime)); }
public SignerResponse Sign( SignatureType mode, GostFlavor gostFlavor, string certificateThumbprint, byte[] bytesToSign, string nodeToSign, bool ignoreExpiredCert = false, bool?isAddSigningTime = null) { XmlDocument xmlToSign = null; string stringToSign = null; bool isResultBase64Bytes = false; if (mode == SignatureType.Pkcs7String || mode == SignatureType.Pkcs7StringAllCert || mode == SignatureType.Pkcs7StringNoCert || mode == SignatureType.Rsa2048Sha256String || mode == SignatureType.RsaSha256String) { // read binary content as string stringToSign = Encoding.UTF8.GetString(bytesToSign); isResultBase64Bytes = true; } else if (mode == SignatureType.SigDetached || mode == SignatureType.SigDetachedAllCert || mode == SignatureType.SigDetachedNoCert) { // TODO: this is a quick and dirty fix // here we already have content in bytesToSign - just do nothing isResultBase64Bytes = true; } else { xmlToSign = new XmlDocument(); var stringContent = Encoding.UTF8.GetString(bytesToSign); xmlToSign.LoadXml(stringContent); } //TODO: this is a very convoluted way to pass arguments. Wrap all possible input data into a class!!! var signedData = Sign( mode, gostFlavor, certificateThumbprint, xmlToSign, false, nodeToSign, ignoreExpiredCert, stringToSign, string.IsNullOrEmpty(stringToSign) ? bytesToSign : null, isAddSigningTime); return(new SignerResponse(signedData, isResultBase64Bytes)); }
private XmlDocument SignSmev2(GostFlavor gostFlavor, XmlDocument doc, X509Certificate2 certificate) { XmlNode root = doc.SelectSingleNode("/*"); string rootPrefix = root?.Prefix; //----------------------------------------------------------------------------------------------CREATE STRUCTURE XmlDocument tDoc = AddTemplate(doc, certificate); //----------------------------------------------------------------------------------------------ROOT PREFIX XmlElement bodyElement = tDoc.GetElementsByTagName(rootPrefix + ":Body")[0] as XmlElement; string referenceUri = bodyElement?.GetAttribute("wsu:Id"); //----------------------------------------------------------------------------------------------SignedXML CREATE //нужен для корректной отработки wsu:reference Smev2SignedXml signedXml = new Smev2SignedXml(tDoc) { SigningKey = certificate.PrivateKey }; //----------------------------------------------------------------------------------------------REFERNCE Reference reference = new Reference { #pragma warning disable 612 DigestMethod = GostAlgorithmSelector.GetHashAlgorithmDescriptor(gostFlavor), //CPSignedXml.XmlDsigGost3411UrlObsolete, #pragma warning restore 612 Uri = "#" + referenceUri }; XmlDsigExcC14NTransform c14 = new XmlDsigExcC14NTransform(); reference.AddTransform(c14); signedXml.AddReference(reference); //----------------------------------------------------------------------------------------------SIGNATURE SETUP signedXml.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigExcC14NTransformUrl; #pragma warning disable 612 signedXml.SignedInfo.SignatureMethod = GostAlgorithmSelector.GetSignatureAlgorithmDescriptor(gostFlavor); //CPSignedXml.XmlDsigGost3410UrlObsolete; #pragma warning disable 612 //----------------------------------------------------------------------------------------------KEYINFO KeyInfo keyInfo = new KeyInfo(); KeyInfoX509Data x509KeyInfo = new KeyInfoX509Data(certificate); keyInfo.AddClause(x509KeyInfo); signedXml.KeyInfo = keyInfo; //----------------------------------------------------------------------------------------------SIGN DOCUMENT signedXml.ComputeSignature(); //----------------------------------------------------------------------------------------------GET XML XmlElement xmlDigitalSignature = signedXml.GetXml(); //----------------------------------------------------------------------------------------------APPEND SIGNATURE TAGS tDoc.GetElementsByTagName("Signature")[0].PrependChild( tDoc.ImportNode(xmlDigitalSignature.GetElementsByTagName("SignatureValue")[0], true)); tDoc.GetElementsByTagName("Signature")[0].PrependChild( tDoc.ImportNode(xmlDigitalSignature.GetElementsByTagName("SignedInfo")[0], true)); ((XmlElement)tDoc.GetElementsByTagName("Signature")[0]).SetAttribute("xmlns", DS_NS); return(tDoc); }
public string Sign( SignatureType mode, GostFlavor gostFlavor, XmlDocument signThis, string certificateThumbprint, string nodeToSign, bool assignDs = false, bool ignoreExpiredCert = false, bool?isAddSigningTime = null) { return(Sign(mode, gostFlavor, certificateThumbprint, signThis, assignDs, nodeToSign, ignoreExpiredCert, isAddSigningTime: isAddSigningTime)); }
private XmlDocument SignEnveloped( GostFlavor gostFlavor, XmlDocument doc, X509Certificate2 certificate, string nodeId = null) { //----------------------------------------------------------------------------------------------CREATE SIGNED XML SignedXml signedXml = new SignedXml(doc) { SigningKey = certificate.PrivateKey }; //----------------------------------------------------------------------------------------------REFERNCE Reference reference = new Reference { Uri = nodeId, #pragma warning disable 612 DigestMethod = GostAlgorithmSelector.GetHashAlgorithmDescriptor(gostFlavor) //CPSignedXml.XmlDsigGost3411UrlObsolete - old #pragma warning disable 612 }; XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform(); reference.AddTransform(env); XmlDsigExcC14NTransform c14 = new XmlDsigExcC14NTransform(); reference.AddTransform(c14); // Add the reference to the SignedXml object. signedXml.AddReference(reference); //----------------------------------------------------------------------------------------------SIGNATURE SETUP signedXml.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigExcC14NTransformUrl; signedXml.SignedInfo.SignatureMethod = GostAlgorithmSelector.GetSignatureAlgorithmDescriptor(gostFlavor); //CPSignedXml.XmlDsigGost3410UrlObsolete; - old //----------------------------------------------------------------------------------------------KEYINFO KeyInfo keyInfo = new KeyInfo(); KeyInfoX509Data x509KeyInfo = new KeyInfoX509Data(certificate); keyInfo.AddClause(x509KeyInfo); signedXml.KeyInfo = keyInfo; //----------------------------------------------------------------------------------------------SIGN DOCUMENT signedXml.ComputeSignature(); //----------------------------------------------------------------------------------------------GET XML XmlElement xmlDigitalSignature = signedXml.GetXml(); //----------------------------------------------------------------------------------------------APPEND SIGNATURE XmlNode root = doc.SelectSingleNode("/*"); root?.AppendChild(doc.ImportNode(xmlDigitalSignature, true)); return(doc); }
private XmlDocument SignXmlNode( GostFlavor gostFlavor, XmlDocument doc, X509Certificate2 certificate, string nodeId) { //----------------------------------------------------------------------------------------------CREATE SIGNED XML SignedXml signedXml = new SignedXml(doc) { SigningKey = certificate.PrivateKey }; //----------------------------------------------------------------------------------------------REFERNCE Reference reference = new Reference { Uri = "#" + nodeId, #pragma warning disable 612 DigestMethod = GostAlgorithmSelector.GetHashAlgorithmDescriptor(gostFlavor) //CPSignedXml.XmlDsigGost3411UrlObsolete - old #pragma warning disable 612 }; XmlDsigExcC14NTransform c14 = new XmlDsigExcC14NTransform(); reference.AddTransform(c14); // Add the reference to the SignedXml object. signedXml.AddReference(reference); //----------------------------------------------------------------------------------------------SIGNATURE SETUP signedXml.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigExcC14NTransformUrl; signedXml.SignedInfo.SignatureMethod = GostAlgorithmSelector.GetSignatureAlgorithmDescriptor(gostFlavor); //CPSignedXml.XmlDsigGost3410UrlObsolete; //----------------------------------------------------------------------------------------------KEYINFO KeyInfo keyInfo = new KeyInfo(); KeyInfoX509Data x509KeyInfo = new KeyInfoX509Data(certificate); keyInfo.AddClause(x509KeyInfo); signedXml.KeyInfo = keyInfo; //----------------------------------------------------------------------------------------------SIGN DOCUMENT signedXml.ComputeSignature(); //----------------------------------------------------------------------------------------------GET XML XmlElement xmlDigitalSignature = signedXml.GetXml(); //=============================================================================APPEND SIGNATURE TO DOCUMENT GetNodeWithAttributeValue(doc.ChildNodes, nodeId)?.ParentNode?.AppendChild(xmlDigitalSignature); return(doc); }
public static string GetHashAlgorithmDescriptor(GostFlavor gostFlavor) { switch (gostFlavor) { case GostFlavor.Gost_Obsolete: #pragma warning disable 612 return(CPSignedXml.XmlDsigGost3411UrlObsolete); #pragma warning restore 612 case GostFlavor.Gost2012_256: return(CPSignedXml.XmlDsigGost3411_2012_256Url); case GostFlavor.Gost2012_512: return(CPSignedXml.XmlDsigGost3411_2012_512Url); default: throw new ArgumentOutOfRangeException(nameof(gostFlavor), gostFlavor, null); } }
private string Sign( SignatureType mode, GostFlavor gostFlavor, X509Certificate2 cert, XmlDocument signThis, bool assignDs, string nodeToSign, string stringToSign = null, byte[] bytesToSign = null, bool?isAddSigningTime = null) { XmlDocument signedXmlDoc = new XmlDocument(); try { switch (mode) { case SignatureType.Smev2SidebysideDetached: if (string.IsNullOrEmpty(nodeToSign)) { throw ExceptionFactory.GetException(ExceptionType.NodeIdRequired); } signedXmlDoc = SignXmlNode(gostFlavor, signThis, cert, nodeToSign); break; case SignatureType.Smev2ChargeEnveloped: signedXmlDoc = SignEnveloped(gostFlavor, signThis, cert); break; case SignatureType.Smev2BaseDetached: signedXmlDoc = SignSmev2(gostFlavor, signThis, cert); break; case SignatureType.Smev3BaseDetached: if (string.IsNullOrEmpty(nodeToSign)) { throw ExceptionFactory.GetException(ExceptionType.NodeIdRequired); } signedXmlDoc = SignSmev3(gostFlavor, signThis, cert, nodeToSign, assignDs); break; case SignatureType.Smev3SidebysideDetached: if (string.IsNullOrEmpty(nodeToSign)) { throw ExceptionFactory.GetException(ExceptionType.NodeIdRequired); } signedXmlDoc = SignSmev3( gostFlavor, signThis, cert, nodeToSign, assignDs, isAck: false, isSidebyside: true); break; case SignatureType.Smev3Ack: if (string.IsNullOrEmpty(nodeToSign)) { throw ExceptionFactory.GetException(ExceptionType.NodeIdRequired); } signedXmlDoc = SignSmev3(gostFlavor, signThis, cert, nodeToSign, assignDs, isAck: true); break; case SignatureType.SigDetached: return(Convert.ToBase64String(SignPkcs7(bytesToSign, cert, X509IncludeOption.EndCertOnly, isAddSigningTime ?? false))); case SignatureType.SigDetachedNoCert: return(Convert.ToBase64String(SignPkcs7(bytesToSign, cert, X509IncludeOption.None, isAddSigningTime ?? false))); case SignatureType.SigDetachedAllCert: return(Convert.ToBase64String(SignPkcs7(bytesToSign, cert, X509IncludeOption.WholeChain, isAddSigningTime ?? false))); case SignatureType.Pkcs7String: return(Convert.ToBase64String( SignStringPkcs7(stringToSign, cert, X509IncludeOption.EndCertOnly, isAddSigningTime ?? false))); case SignatureType.Pkcs7StringNoCert: return(Convert.ToBase64String(SignStringPkcs7(stringToSign, cert, X509IncludeOption.None, isAddSigningTime ?? false))); case SignatureType.Pkcs7StringAllCert: return(Convert.ToBase64String( SignStringPkcs7(stringToSign, cert, X509IncludeOption.WholeChain, isAddSigningTime ?? false))); case SignatureType.Rsa2048Sha256String: return(Convert.ToBase64String(SignStringRsa2048Sha256(stringToSign, cert))); case SignatureType.RsaSha256String: return(Convert.ToBase64String(SignStringRsaSha(stringToSign, cert, ShaAlgorithmType.Sha256))); } } catch (Exception e) { throw ExceptionFactory.GetException(ExceptionType.UnknownSigningException, e.Message); } return(signedXmlDoc.InnerXml); }
private XmlDocument SignSmev3( GostFlavor gostFlavor, XmlDocument doc, X509Certificate2 certificate, string signingNodeId, bool assignDs, bool isAck = false, bool isSidebyside = false) { XmlNamespaceManager nsm = new XmlNamespaceManager(doc.NameTable); nsm.AddNamespace("ns", "urn://x-artefacts-smev-gov-ru/services/message-exchange/types/1.1"); nsm.AddNamespace("ns1", "urn://x-artefacts-smev-gov-ru/services/message-exchange/types/basic/1.1"); nsm.AddNamespace("ds", "http://www.w3.org/2000/09/xmldsig#"); SignedXml sxml = new SignedXml(doc) { SigningKey = certificate.PrivateKey }; XmlDsigSmevTransform smevTransform = new XmlDsigSmevTransform(); sxml.SafeCanonicalizationMethods.Add(smevTransform.Algorithm); //=====================================================================================REFERENCE TRASFORMS Reference reference = new Reference { Uri = "#" + signingNodeId, #pragma warning disable 612 //Расчет хеш-суммы ГОСТ Р 34.11-94 / 34.11.2012 http://www.w3.org/2001/04/xmldsig-more#gostr3411 DigestMethod = GostAlgorithmSelector.GetHashAlgorithmDescriptor(gostFlavor) //CPSignedXml.XmlDsigGost3411UrlObsolete - old one #pragma warning disable 612 }; XmlDsigExcC14NTransform excC14N = new XmlDsigExcC14NTransform(); reference.AddTransform(excC14N); reference.AddTransform(smevTransform); if (isAck) { XmlDsigEnvelopedSignatureTransform enveloped = new XmlDsigEnvelopedSignatureTransform(); reference.AddTransform(enveloped); } sxml.AddReference(reference); //=========================================================================================CREATE SIGNATURE sxml.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigExcC14NTransformUrl; //Формирование подписи ГОСТ Р 34.10-2001 / 34.10-2012 http://www.w3.org/2001/04/xmldsig-more#gostr34102001-gostr3411 sxml.SignedInfo.SignatureMethod = GostAlgorithmSelector.GetSignatureAlgorithmDescriptor(gostFlavor); //CPSignedXml.XmlDsigGost3410UrlObsolete; - old one KeyInfo keyInfo = new KeyInfo(); KeyInfoX509Data x509KeyInfo = new KeyInfoX509Data(certificate); keyInfo.AddClause(x509KeyInfo); sxml.KeyInfo = keyInfo; sxml.ComputeSignature(); XmlElement signature = sxml.GetXml(); //==================================================================================================add ds: if (assignDs) { AssignNsPrefix(signature, "ds"); XmlElement xmlSignedInfo = signature.SelectSingleNode("ds:SignedInfo", nsm) as XmlElement; XmlDocument document = new XmlDocument(); document.PreserveWhitespace = false; document.LoadXml(xmlSignedInfo.OuterXml); //create new canonicalization object based on original one Transform canonicalizationMethodObject = sxml.SignedInfo.CanonicalizationMethodObject; canonicalizationMethodObject.LoadInput(document); //get new hshing object based on original one SignatureDescription description = CryptoConfig.CreateFromName(sxml.SignedInfo.SignatureMethod) as SignatureDescription; if (description == null) { throw new CryptographicException( $"Не удалось создать объект SignatureDescription по имени [{sxml.SignedInfo.SignatureMethod}]"); } HashAlgorithm hash = description.CreateDigest(); if (hash == null) { throw new CryptographicException( $"Не удалось создать объект HashAlgorithm из SignatureDescription по имени [{sxml.SignedInfo.SignatureMethod}]"); } //compute new SignedInfo digest value byte[] hashVal = canonicalizationMethodObject.GetDigestedOutput(hash); //compute new signature XmlElement xmlSignatureValue = signature.SelectSingleNode("ds:SignatureValue", nsm) as XmlElement; xmlSignatureValue.InnerText = Convert.ToBase64String(description.CreateFormatter(sxml.SigningKey).CreateSignature(hashVal)); } //=============================================================================APPEND SIGNATURE TO DOCUMENT if (!isSidebyside) { //TODO: is using SMEV types 1.2 edit this code! doc.GetElementsByTagName( "CallerInformationSystemSignature", "urn://x-artefacts-smev-gov-ru/services/message-exchange/types/1.1")[0].InnerXml = ""; doc.GetElementsByTagName( "CallerInformationSystemSignature", "urn://x-artefacts-smev-gov-ru/services/message-exchange/types/1.1")[0].AppendChild(signature); } else { GetNodeWithAttributeValue(doc.ChildNodes, signingNodeId)?.ParentNode?.AppendChild(signature); } return(doc); }