private KeyInfo getKeyInfo() { X509Extension extension = this.settings.Certificate.Extensions[1]; AsnEncodedData asndata = new AsnEncodedData(extension.Oid, extension.RawData); KeyInfoX509Data keyInfoData = new KeyInfoX509Data(); keyInfoData.AddIssuerSerial(this.settings.Certificate.Issuer, this.settings.Certificate.SerialNumber); keyInfoData.AddSubjectName(this.settings.Certificate.SubjectName.Name); KeyInfo keyInfo = new KeyInfo(); keyInfo.AddClause(keyInfoData); return keyInfo; }
public static void SignXml(ref XmlDocument document, X509Certificate2 certificate, RequestType requestType) { document.PreserveWhitespace = true; if (requestType == RequestType.Invoice || requestType == RequestType.Buisness_premise) { XmlNode nodeTaxNumber = document.GetElementsByTagName("fu:TaxNumber")[0]; nodeTaxNumber.InnerText = AppLink.VATNumber; string taxNumber = nodeTaxNumber.InnerText; if (requestType == RequestType.Invoice) { string issueDate = DateTime.Now.ToUniversalTime().ToString("s"); XmlNode nodeIssueDate = document.GetElementsByTagName("fu:IssueDateTime")[0]; nodeIssueDate.InnerText = issueDate; XmlNode nodeInvoiceNumber = document.GetElementsByTagName("fu:InvoiceNumber")[0]; string invoiceNumber = nodeInvoiceNumber.InnerText; XmlNode nodeBusinessPremiseID = document.GetElementsByTagName("fu:BusinessPremiseID")[0]; string businessPremiseID = nodeBusinessPremiseID.InnerText; XmlNode nodeElectronicDeviceID = document.GetElementsByTagName("fu:ElectronicDeviceID")[0]; string electronicDeviceID = nodeElectronicDeviceID.InnerText; XmlNode nodeInvoiceAmount = document.GetElementsByTagName("fu:InvoiceAmount")[0]; string invoiceAmount = nodeInvoiceAmount.InnerText; string zoi = CalculateZOI(taxNumber, issueDate, invoiceNumber, businessPremiseID, electronicDeviceID, invoiceAmount, certificate); XmlNode nodeZoi = document.GetElementsByTagName("fu:ProtectedID")[0]; nodeZoi.InnerText = zoi; } } CryptoConfig.AddAlgorithm(typeof(RSAPKCS1SHA256SignatureDescription), "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"); if (document == null) throw new ArgumentException("xmlDoc"); // Create a SignedXml object. SignedXml signedXml = new SignedXml(document); byte[] data = certificate.GetPublicKey(); string base64 = Convert.ToBase64String(data); RSACryptoServiceProvider rsaCSP = (RSACryptoServiceProvider)certificate.PrivateKey; CspParameters cspParameters = new CspParameters(); cspParameters.KeyContainerName = rsaCSP.CspKeyContainerInfo.KeyContainerName; cspParameters.KeyNumber = rsaCSP.CspKeyContainerInfo.KeyNumber == KeyNumber.Exchange ? 1 : 2; RSACryptoServiceProvider rsaAesCSP = new RSACryptoServiceProvider(cspParameters); signedXml.SigningKey = rsaAesCSP; //newKey; KeyInfo keyInfo = new KeyInfo(); KeyInfoX509Data keyInfoData = new KeyInfoX509Data(); keyInfoData.AddIssuerSerial(certificate.Issuer, certificate.SerialNumber); X509Extension extension = certificate.Extensions[1]; AsnEncodedData asndata = new AsnEncodedData(extension.Oid, extension.RawData); keyInfoData.AddSubjectName(certificate.SubjectName.Name); // Create a reference to be signed. Reference reference = new Reference(); reference.Uri = "#test"; reference.DigestMethod = @"http://www.w3.org/2001/04/xmlenc#sha256"; // Add an enveloped transformation to the reference. XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform(); reference.AddTransform(env); // Add the reference to the SignedXml object. signedXml.AddReference(reference); keyInfo.AddClause(keyInfoData); signedXml.KeyInfo = keyInfo; signedXml.SignedInfo.SignatureMethod = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"; // Compute the signature. signedXml.ComputeSignature(); // Get the XML representation of the signature and save // it to an XmlElement object. XmlElement xmlDigitalSignature = signedXml.GetXml(); XmlNode element; if (requestType == RequestType.Invoice) { element = document.GetElementsByTagName("fu:InvoiceRequest")[0]; } else { element = document.GetElementsByTagName("fu:BusinessPremiseRequest")[0]; } element.AppendChild(xmlDigitalSignature); }
/////////////////////////////////////////////////////////////////////// /// /// <summary> /// Carry out the Sign command. /// </summary> /// static void DoSignCommand(string title, X509Certificate2 certificate) { Console.WriteLine(); Console.WriteLine("Signing Xml file \"" + fileNames[0] + "\"..."); Console.WriteLine(); // display more details for verbose operation. if (verbose) { DisplayDetail(null, certificate, detached); } SignedXml signedXml = new SignedXml(); ICspAsymmetricAlgorithm csp = (ICspAsymmetricAlgorithm) certificate.PrivateKey; if (csp.CspKeyContainerInfo.RandomlyGenerated) throw new InternalException("Internal error: This certificate does not have a corresponding private key."); signedXml.SigningKey = (AsymmetricAlgorithm) csp; Console.WriteLine(signedXml.SigningKey.ToXmlString(false)); if (detached) { Reference reference = new Reference(); reference.Uri = "file://" + Path.GetFullPath((string) fileNames[0]); signedXml.AddReference(reference); } else { Reference reference = new Reference(); reference.Uri = "#object-1"; // Add an object XmlDocument dataObject = new XmlDocument(); dataObject.PreserveWhitespace = true; XmlElement dataElement = (XmlElement) dataObject.CreateElement("DataObject", SignedXml.XmlDsigNamespaceUrl); dataElement.AppendChild(dataObject.CreateTextNode(new UTF8Encoding(false).GetString(ReadFile((string) fileNames[0])))); dataObject.AppendChild(dataElement); DataObject obj = new DataObject(); obj.Data = dataObject.ChildNodes; obj.Id = "object-1"; signedXml.AddObject(obj); signedXml.AddReference(reference); } signedXml.KeyInfo = new KeyInfo(); if (includeOptions.Count == 0) { signedXml.KeyInfo.AddClause(new KeyInfoX509Data(certificate, X509IncludeOption.ExcludeRoot)); } else { KeyInfoX509Data keyInfoX509Data = new KeyInfoX509Data(); foreach (IncludeOptions includeOption in includeOptions) { switch (includeOption) { case IncludeOptions.ExcludeRoot: case IncludeOptions.EndCertOnly: case IncludeOptions.WholeChain: keyInfoX509Data = new KeyInfoX509Data(certificate, (X509IncludeOption) includeOption); break; case IncludeOptions.SubjectName: keyInfoX509Data.AddSubjectName(certificate.SubjectName.Name); break; case IncludeOptions.SKI: X509ExtensionCollection extensions = certificate.Extensions; foreach (X509Extension extension in extensions) { if (extension.Oid.Value == "2.5.29.14") { // OID for SKI extension X509SubjectKeyIdentifierExtension ski = extension as X509SubjectKeyIdentifierExtension; if (ski != null) { keyInfoX509Data.AddSubjectKeyId(ski.SubjectKeyIdentifier); break; } } } break; case IncludeOptions.IssuerSerial: keyInfoX509Data.AddIssuerSerial(certificate.IssuerName.Name, certificate.SerialNumber); break; } signedXml.KeyInfo.AddClause(keyInfoX509Data); } } // compute the signature signedXml.ComputeSignature(); XmlElement xmlDigitalSignature = signedXml.GetXml(); // write it out XmlTextWriter xmltw = new XmlTextWriter((string) fileNames[1], new UTF8Encoding(false)); xmlDigitalSignature.WriteTo(xmltw); xmltw.Close(); Console.WriteLine(); Console.WriteLine("Signature written to file \"" + fileNames[1] + "\"."); Console.WriteLine(); return; }
public void Complex () { KeyInfoX509Data data1 = new KeyInfoX509Data (cert); KeyInfoX509Data data2 = new KeyInfoX509Data (); XmlElement xel = data1.GetXml (); data2.LoadXml (xel); Assert.AreEqual ((data1.GetXml ().OuterXml), (data2.GetXml ().OuterXml), "data1==data2"); byte[] c = (data1.Certificates[0] as X509Certificate).GetRawCertData(); AssertCrypto.AssertEquals ("Certificate[0]", cert, c); // add a second X.509 certificate X509Certificate x509 = new X509Certificate (cert2); data1.AddCertificate (x509); xel = data1.GetXml (); data2.LoadXml (xel); Assert.AreEqual ((data1.GetXml ().OuterXml), (data2.GetXml ().OuterXml), "data1==data2"); c = (data1.Certificates [1] as X509Certificate).GetRawCertData(); Assert.AreEqual (cert2, c, "Certificate[1]"); // add properties from a third X.509 certificate x509 = new X509Certificate (cert3); data1.AddIssuerSerial (x509.GetIssuerName (), x509.GetSerialNumberString ()); xel = data1.GetXml (); data2.LoadXml (xel); Assert.AreEqual ((data1.GetXml ().OuterXml), (data2.GetXml ().OuterXml), "data1==data2"); // TODO: The type of IssuerSerial isn't documented // X509Certificate doesn't export SubjectKeyId so we must improvise byte[] skid = { 0xDE, 0xAD, 0xC0, 0xDE }; data1.AddSubjectKeyId (skid); xel = data1.GetXml (); data2.LoadXml (xel); Assert.AreEqual ((data1.GetXml ().OuterXml), (data2.GetXml ().OuterXml), "data1==data2"); Assert.AreEqual (skid, (byte[])data1.SubjectKeyIds[0], "SubjectKeyId"); data1.AddSubjectName (x509.GetName ()); xel = data1.GetXml (); data2.LoadXml (xel); Assert.AreEqual ((data1.GetXml ().OuterXml), (data2.GetXml ().OuterXml), "data1==data2"); string s = (string) data1.SubjectNames [0]; Assert.AreEqual (x509.GetName (), s, "SubjectName"); }
public void AddIssuerSerial_Issuer_Null () { KeyInfoX509Data data = new KeyInfoX509Data (); data.AddIssuerSerial ("issuer", null); }
public void AddIssuerSerial_Null_Serial () { KeyInfoX509Data data = new KeyInfoX509Data (); data.AddIssuerSerial (null, "serial"); }
public void AddIssuerSerial_Issuer_Null () { KeyInfoX509Data data = new KeyInfoX509Data (); data.AddIssuerSerial ("issuer", null); XmlElement empty = data.GetXml (); Assert.AreEqual (empty.OuterXml, "<X509Data xmlns=\"http://www.w3.org/2000/09/xmldsig#\"><X509IssuerSerial><X509IssuerName>issuer</X509IssuerName><X509SerialNumber></X509SerialNumber></X509IssuerSerial></X509Data>"); }
public static void SignDetachedResource(string inputFile, string outputSignatureXML, string certFile, String certPassword) { X509Certificate2 certxml = new X509Certificate2(certFile, certPassword); RSACryptoServiceProvider Key = (RSACryptoServiceProvider)certxml.PrivateKey; String XmlSigFileName = outputSignatureXML; // Sign the detached resourceand save the signature in an XML file. // Create a SignedXml object. SignedXml signedXml = new SignedXml(); // Assign the key to the SignedXml object. signedXml.SigningKey = Key; // Create a reference to be signed. Reference reference = new Reference(); // Add the passed Refrence to the reference object. reference.Uri = inputFile; // Add the reference to the SignedXml object. signedXml.AddReference(reference); // Add an RSAKeyValue KeyInfo (optional; helps recipient find key to validate). KeyInfo keyInfo = new KeyInfo(); keyInfo.AddClause(new RSAKeyValue((RSA)Key)); if (certxml != null) { KeyInfoX509Data kinfox509 = new KeyInfoX509Data(certxml, X509IncludeOption.WholeChain); kinfox509.AddIssuerSerial(certxml.Issuer, certxml.SerialNumber); kinfox509.AddSubjectName(certxml.Subject); keyInfo.AddClause(kinfox509); } signedXml.KeyInfo = keyInfo; // Compute the signature. signedXml.ComputeSignature(); // Get the XML representation of the signature and save // it to an XmlElement object. XmlElement xmlDigitalSignature = signedXml.GetXml(); // Save the signed XML document to a file specified // using the passed string. XmlTextWriter xmltw = new XmlTextWriter(XmlSigFileName, new UTF8Encoding(false)); xmlDigitalSignature.WriteTo(xmltw); xmltw.Close(); }
public static void SignDetachedResourceWithToken(String inputFile, String outputXmlFile, String tokenPassword, String KeyContainerName) { var pass = new SecureString(); foreach (char c in tokenPassword.ToCharArray()) { pass.AppendChar(c); } CspParameters csp = new CspParameters(1, CertUtils.ProviderName, KeyContainerName, new System.Security.AccessControl.CryptoKeySecurity(), pass); try { RSACryptoServiceProvider rsaCsp = new RSACryptoServiceProvider(csp); // the pin code will be cached for next access to the smart card } catch (Exception ex) { Console.WriteLine("Crypto error: " + ex.Message); return; } X509Store store = new X509Store("My"); store.Open(OpenFlags.ReadOnly); X509Certificate2 cert = null; foreach (X509Certificate2 cert2 in store.Certificates) { if (cert2.HasPrivateKey) { RSACryptoServiceProvider rsa = (RSACryptoServiceProvider)cert2.PrivateKey; if (rsa == null) continue; // not smart card cert again if (rsa.CspKeyContainerInfo.HardwareDevice) // sure - smartcard { if ((rsa.CspKeyContainerInfo.KeyContainerName == CertUtils.KeyContainerName) && (rsa.CspKeyContainerInfo.ProviderName == CertUtils.ProviderName)) { //we find it cert = cert2; break; } } } } if (cert == null) { Console.WriteLine("Certificate not found"); return; } RSACryptoServiceProvider tokenKey = (RSACryptoServiceProvider)cert.PrivateKey; // Sign the detached resourceand save the signature in an XML file. // Create a SignedXml object. SignedXml signedXml = new SignedXml(); // Assign the key to the SignedXml object. signedXml.SigningKey = tokenKey; // Create a reference to be signed. Reference reference = new Reference(); // Add the passed Refrence to the reference object. reference.Uri = inputFile; // Add the reference to the SignedXml object. signedXml.AddReference(reference); // Add an RSAKeyValue KeyInfo (optional; helps recipient find key to validate). KeyInfo keyInfo = new KeyInfo(); keyInfo.AddClause(new RSAKeyValue((RSA)tokenKey)); if (cert != null) { KeyInfoX509Data kinfox509 = new KeyInfoX509Data(cert, X509IncludeOption.EndCertOnly); kinfox509.AddIssuerSerial(cert.Issuer, cert.SerialNumber); kinfox509.AddSubjectName(cert.Subject); keyInfo.AddClause(kinfox509); } signedXml.KeyInfo = keyInfo; // Compute the signature. signedXml.ComputeSignature(); // Get the XML representation of the signature and save // it to an XmlElement object. XmlElement xmlDigitalSignature = signedXml.GetXml(); // Save the signed XML document to a file specified // using the passed string. XmlTextWriter xmltw = new XmlTextWriter(outputXmlFile, new UTF8Encoding(false)); xmlDigitalSignature.WriteTo(xmltw); xmltw.Close(); }
/// <summary> /// Signs the SOAP document and adds a digital signature to it. /// /// Note a lot of optional settings are applied against /// key and certificate info to match the required XML document /// structure the server requests. /// </summary> /// <param name="xmlDoc"></param> /// <param name="certFriendlyName">Friendly Name of Cert installed in the Certificate Store under CurrentUser | Personal</param> /// <returns></returns> public XmlDocument SignSoapBody(XmlDocument xmlDoc, X509Certificate2 cert) { // *** Add search Namespaces references to ensure we can reliably work // *** against any SOAP docs regardless of tag naming XmlNamespaceManager ns = new XmlNamespaceManager(xmlDoc.NameTable); ns.AddNamespace("SOAP", STR_SOAP_NS); ns.AddNamespace("SOAP-SEC", STR_SOAPSEC_NS); // *** Grab the body element - this is what we create the signature from XmlElement body = xmlDoc.DocumentElement.SelectSingleNode(@"//SOAP:Body", ns) as XmlElement; if (body == null) throw new ApplicationException("No body tag found"); // *** We'll only encode the <SOAP:Body> - add id: Reference as #Body body.SetAttribute("id", "Body"); // *** Signed XML will create Xml Signature - Xml fragment SignedXml signedXml = new SignedXml(xmlDoc); // *** Create a KeyInfo structure KeyInfo keyInfo = new KeyInfo(); // *** The actual key for signing - MAKE SURE THIS ISN'T NULL! signedXml.SigningKey = cert.PrivateKey; // *** Specifically use the issuer and serial number for the data rather than the default KeyInfoX509Data keyInfoData = new KeyInfoX509Data(); keyInfoData.AddIssuerSerial(cert.Issuer, cert.GetSerialNumberString()); keyInfo.AddClause(keyInfoData); // *** provide the certficate info that gets embedded - note this is only // *** for specific formatting of the message to provide the cert info signedXml.KeyInfo = keyInfo; // *** Again unusual - meant to make the document match template signedXml.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigExcC14NTransformUrl; // *** Now create reference to sign: Point at the Body element Reference reference = new Reference(); reference.Uri = "#Body"; // reference id=body section in same doc reference.AddTransform(new XmlDsigExcC14NTransform()); // required to match doc signedXml.AddReference(reference); // *** Finally create the signature signedXml.ComputeSignature(); // *** Result is an XML node with the signature detail below it // *** Now let's add the sucker into the SOAP-HEADER XmlElement signedElement = signedXml.GetXml(); // *** Create SOAP-SEC:Signature element XmlElement soapSignature = xmlDoc.CreateElement("Signature", STR_SOAPSEC_NS); soapSignature.Prefix = "SOAP-SEC"; soapSignature.SetAttribute("MustUnderstand", "", "1"); // *** And add our signature as content soapSignature.AppendChild(signedElement); // *** Now add the signature header into the master header XmlElement soapHeader = xmlDoc.DocumentElement.SelectSingleNode("//SOAP:Header", ns) as XmlElement; if (soapHeader == null) { soapHeader = xmlDoc.CreateElement("Header", STR_SOAP_NS); soapHeader.Prefix = "SOAP"; xmlDoc.DocumentElement.InsertBefore(soapHeader, xmlDoc.DocumentElement.ChildNodes[0]); } soapHeader.AppendChild(soapSignature); return xmlDoc; }
//source http://objectmix.com/dotnet/794749-digitally-sign-xml-doc-x509certificate-solution.html //which came from the msdn tutorial //Certificate get Signature method private XmlElement SignXml(XmlDocument xmlDoc, X509Certificate2 cert) { //preserve ws - difference here I noticed - mine was set to true xmlDoc.PreserveWhitespace = false; // Create a SignedXml object. SignedXml signedXml = new SignedXml(xmlDoc); // Load the certificate into a KeyInfoX509Data object // and add it to the KeyInfo object. //// Add an RSAKeyValue KeyInfo (optional; helps recipient find key to validate). KeyInfo keyInfo = new KeyInfo(); if (map.getProperty(DigSigUtil.SIGNATURE_OPTION_CERT_INCLUSION_BASE64).Equals("true", StringComparison.CurrentCultureIgnoreCase)) keyInfo.AddClause(new KeyInfoX509Data(cert)); if (map.getProperty(DigSigUtil.SIGNATURE_OPTION_CERT_INCLUSION_SUBJECTDN).Equals("true", StringComparison.CurrentCultureIgnoreCase)) { KeyInfoX509Data data = new KeyInfoX509Data(); data.AddSubjectName(cert.SubjectName.Name); keyInfo.AddClause(data); } if (map.getProperty(DigSigUtil.SIGNATURE_OPTION_CERT_INCLUSION_SERIAL).Equals("true", StringComparison.CurrentCultureIgnoreCase)) { KeyInfoX509Data data = new KeyInfoX509Data(); data.AddIssuerSerial(cert.IssuerName.Name, cert.SerialNumber); keyInfo.AddClause(data); } signedXml.KeyInfo = keyInfo; //CANON method signedXml.SignedInfo.CanonicalizationMethod = map.getProperty(DigSigUtil.CANONICALIZATIONMETHOD); if (String.IsNullOrEmpty(signedXml.SignedInfo.CanonicalizationMethod)) signedXml.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigExcC14NWithCommentsTransformUrl; signedXml.SignedInfo.SignatureMethod = map.getProperty(DigSigUtil.SIGNATURE_METHOD); if (String.IsNullOrEmpty(signedXml.SignedInfo.SignatureMethod)) signedXml.SignedInfo.SignatureMethod = SignedXml.XmlDsigRSASHA1Url; // Set the rsaKey to the certificate's private key RSACryptoServiceProvider rsaKey = (RSACryptoServiceProvider)cert.PrivateKey; // Add the key to the SignedXml document. signedXml.SigningKey = rsaKey; // Create a reference to be signed. Reference reference = new Reference(); reference.Uri = ""; // Add an enveloped transformation to the reference. XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform(); reference.AddTransform(env); // Add the reference to the SignedXml object. signedXml.AddReference(reference); // Now we can compute the signature. signedXml.ComputeSignature(); return signedXml.GetXml(); // return signedXml; }