Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- public static class GisSignatureHelper
- {
- public const bool PreserveWhitespace = true;
- public static string GetSignedRequestXades(string request, string thumbprint, string privateKeyPassword)
- {
- var originalDoc = new XmlDocument { PreserveWhitespace = PreserveWhitespace };
- originalDoc.LoadXml(request);
- var cert = GetCertificateByThumbprint(thumbprint);
- var signatureid = $"xmldsig-{Guid.NewGuid().ToString().ToLower()}";
- var signedXml = GetXadesSignedXml(cert, originalDoc, signatureid, privateKeyPassword);
- var keyInfo = GetKeyInfo(Convert.ToBase64String(cert.GetRawCertData()));
- signedXml.KeyInfo = keyInfo;
- var xadesInfo = GetXadesInfo(cert);
- var xadesObject = GetXadesObject(xadesInfo, signatureid);
- signedXml.AddXadesObject(xadesObject);
- signedXml.ComputeSignature();
- InjectSignatureToOriginalDoc(signedXml, originalDoc);
- return originalDoc.OuterXml;
- }
- public static XadesInfo GetXadesInfo(X509Certificate2 certificate)
- {
- var xadesInfo = new XadesInfo
- {
- RawPK = Convert.ToBase64String(certificate.GetRawCertData()),
- SigningDateTimeUTC = DateTime.UtcNow
- };
- var delta = TimeZoneInfo.Local.GetUtcOffset(DateTime.Now);
- xadesInfo.TimeZoneOffsetMinutes = Convert.ToInt32(delta.TotalMinutes);
- return xadesInfo;
- }
- public static void InjectSignatureToOriginalDoc(XadesSignedXml signedXml, XmlDocument originalDoc)
- {
- var xmlSig = signedXml.GetXml();
- var signedDataContainer = signedXml.GetIdElement(originalDoc, "signed-data-container");
- signedDataContainer.InsertBefore(originalDoc.ImportNode(xmlSig, true), signedDataContainer.FirstChild);
- }
- public static XadesObject GetXadesObject(XadesInfo xadesInfo, string signatureid)
- {
- var xadesObject = new XadesObject
- {
- QualifyingProperties =
- {
- Target = $"#{signatureid}",
- SignedProperties = {Id = $"{signatureid}-signedprops"}
- }
- };
- var signedSignatureProperties = xadesObject.QualifyingProperties.SignedProperties.SignedSignatureProperties;
- var x509CertificateParser = new X509CertificateParser();
- var bouncyCert = x509CertificateParser.ReadCertificate(Convert.FromBase64String(xadesInfo.RawPK));
- var cert = new Cert
- {
- IssuerSerial =
- {
- X509IssuerName = GetOidRepresentation(bouncyCert.IssuerDN.ToString()),
- X509SerialNumber = bouncyCert.SerialNumber.ToString()
- }
- };
- cert.CertDigest.DigestMethod.Algorithm = CPSignedXml.XmlDsigGost3411UrlObsolete;
- var rawCertData = Convert.FromBase64String(xadesInfo.RawPK);
- var pkHash = HashAlgorithm.Create("GOST3411");
- var hashValue = pkHash.ComputeHash(rawCertData);
- cert.CertDigest.DigestValue = hashValue;
- signedSignatureProperties.SigningCertificate.CertCollection.Add(cert);
- signedSignatureProperties.SigningTime = GetSigningTimeOffset(xadesInfo.SigningDateTimeUTC, xadesInfo.TimeZoneOffsetMinutes);
- return xadesObject;
- }
- public static DateTimeOffset GetSigningTimeOffset(DateTime dtUTC, int timeZoneOffsetMinutes)
- {
- var dtUnspecified = DateTime.SpecifyKind(dtUTC.AddMinutes(timeZoneOffsetMinutes), DateTimeKind.Unspecified);
- return new DateTimeOffset(dtUnspecified, new TimeSpan(0, timeZoneOffsetMinutes, 0));
- }
- public static XadesSignedXml GetXadesSignedXml(X509Certificate2 certificate, XmlDocument originalDoc, string signatureid, string privateKeyPassword)
- {
- var secureString = new SecureString();
- foreach (var ch in privateKeyPassword)
- secureString.AppendChar(ch);
- var provider = (Gost3410CryptoServiceProvider)certificate.PrivateKey;
- provider.SetContainerPassword(secureString);
- var signedXml = new XadesSignedXml(originalDoc) { SigningKey = provider };
- signedXml.Signature.Id = signatureid;
- signedXml.SignatureValueId = $"{signatureid}-sigvalue";
- var reference = new Reference
- {
- Uri = "#signed-data-container",
- DigestMethod = CPSignedXml.XmlDsigGost3411UrlObsolete,
- Id = $"{signatureid}-ref0"
- };
- reference.AddTransform(new XmlDsigEnvelopedSignatureTransform());
- reference.AddTransform(new XmlDsigExcC14NTransform());
- signedXml.AddReference(reference);
- signedXml.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigCanonicalizationUrl;
- signedXml.SignedInfo.SignatureMethod = CPSignedXml.XmlDsigGost3410UrlObsolete;
- return signedXml;
- }
- public static KeyInfo GetKeyInfo(string rawPkString)
- {
- var keyInfo = new KeyInfo();
- var doc = new XmlDocument();
- var keyInfoElement = (XmlElement)doc.AppendChild(doc.CreateElement("ds", "KeyInfo", "http://www.w3.org/2000/09/xmldsig#"));
- var x509DataElement = doc.CreateElement("ds", "X509Data", "http://www.w3.org/2000/09/xmldsig#");
- var x509DataNode = keyInfoElement.AppendChild(x509DataElement);
- x509DataNode.AppendChild(doc.CreateElement("ds", "X509Certificate", "http://www.w3.org/2000/09/xmldsig#")).InnerText = rawPkString;
- keyInfo.AddClause(new KeyInfoNode(x509DataElement));
- //keyInfo.AddClause(new KeyInfoX509Data(certificate));
- return keyInfo;
- }
- private static X509Certificate2 GetCertificateByThumbprint(string thumbprint)
- {
- var store = new X509Store("MY", StoreLocation.CurrentUser);
- store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);
- var fcollection = store.Certificates.Find(X509FindType.FindByThumbprint, thumbprint, false);
- var cert = new X509Certificate2();
- foreach (var x509 in fcollection)
- {
- cert = x509;
- }
- return cert;
- }
- /// <summary>
- /// Заменяет части IssuerName на OID. https://technet.microsoft.com/en-us/library/cc772812(WS.10).aspx
- /// </summary>
- /// <param name="issuerName"></param>
- /// <returns></returns>
- private static string GetOidRepresentation(string issuerName)
- {
- var result = issuerName;
- result = result.Replace("E=", "1.2.840.113549.1.9.1=");
- return result;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement