I use an X509 certificate to sign an XML file but the prefix related to the signature is missing, I have to add the "ds" one.
How to add this prefix without having to break my signature?
Here is my code:
Code:
Dim f_adresse As String = System.AppDomain.CurrentDomain.BaseDirectory
Dim f_temp As String = f_adresse & "TEMP\"
Dim f_fichier As String = "20381235051-01-FF12-03.xml"
Dim f_certificat As String = f_adresse & "aG9CcVpHVndCWTd3WlVOVw==.p12"
Dim f_pwd As String = "GiQ5uTsBZ9gHxzNH"
Dim xmlFile As String = f_temp & f_fichier
Dim MonCertificat As X509Certificate2 = New X509Certificate2(f_certificat, f_pwd)
Dim xmlDoc As XmlDocument = New XmlDocument()
xmlDoc.PreserveWhitespace = True
xmlDoc.Load(xmlFile)
Dim signedXml As SignedXml = New SignedXml(xmlDoc)
signedXml.SigningKey = MonCertificat.PrivateKey
Dim KeyInfo As KeyInfo = New KeyInfo()
Dim Reference As Reference = New Reference()
Reference.Uri = ""
Reference.AddTransform(New XmlDsigEnvelopedSignatureTransform("true"))
signedXml.AddReference(Reference)
Dim X509Chain As X509Chain = New X509Chain()
X509Chain.Build(MonCertificat)
Dim local_element As X509ChainElement = X509Chain.ChainElements(0)
Dim x509Data As KeyInfoX509Data = New KeyInfoX509Data(local_element.Certificate)
Dim subjectName As String = local_element.Certificate.Subject
x509Data.AddSubjectName(subjectName)
KeyInfo.AddClause(x509Data)
signedXml.KeyInfo = KeyInfo
signedXml.ComputeSignature()
Dim signature As XmlElement = signedXml.GetXml()
signature.Prefix = "ds"
signedXml.ComputeSignature()
signature.ChildNodes(0).Prefix = "ds" 'this line breaks my signature
signedXml.ComputeSignature()
For Each node As XmlNode In signature.SelectNodes("descendant-or-self::*[namespace-uri()='http://www.w3.org/2000/09/xmldsig#']")
If node.LocalName = "Signature" Then
Dim newAttribute As XmlAttribute = xmlDoc.CreateAttribute("Id")
newAttribute.Value = "SignatureSP"
node.Attributes.Append(newAttribute)
End If
Next node
Dim nsMgr As XmlNamespaceManager
nsMgr = New XmlNamespaceManager(xmlDoc.NameTable)
nsMgr.AddNamespace("sac", "urn:sunat:names:specification:ubl:peru:schema:xsd:SunatAggregateComponents-1")
nsMgr.AddNamespace("ccts", "urn:un:unece:uncefact:documentation:2")
nsMgr.AddNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance")
nsMgr.AddNamespace("tns", "urn:oasis:names:specification:ubl:schema:xsd:Invoice-2")
nsMgr.AddNamespace("cac", "urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2")
nsMgr.AddNamespace("udt", "urn:un:unece:uncefact:data:specification:UnqualifiedDataTypesSchemaModule:2")
nsMgr.AddNamespace("ext", "urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2")
nsMgr.AddNamespace("qdt", "urn:oasis:names:specification:ubl:schema:xsd:QualifiedDatatypes-2")
nsMgr.AddNamespace("cbc", "urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2")
nsMgr.AddNamespace("ds", "http://www.w3.org/2000/09/xmldsig#")
xmlDoc.SelectSingleNode("/tns:Invoice/ext:UBLExtensions/ext:UBLExtension[2]/ext:ExtensionContent", nsMgr).AppendChild(xmlDoc.ImportNode(signature, True))
xmlDoc.Save(xmlFile)
'check the signature
Dim nodeList As XmlNodeList = xmlDoc.GetElementsByTagName("ds:Signature")
If nodeList.Count <= 0 Then
MsgBox("Verification failed: No Signature was found in the document.")
Exit Sub
End If
If nodeList.Count >= 2 Then
MsgBox("Verification failed: More that one signature was found for the document.")
Exit Sub
End If
signedXml.LoadXml(CType(nodeList(0), XmlElement))
msgbox("Check Signature : " & signedXml.CheckSignature())