Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
Hi all,
Today I'm posting a sample which signs an XML with or without a certificate (PFX file) and verifies the signature, all that with .NET and its SignedXml class. I won't include in the sample the code that VS designer includes when I add the textboxes and buttons used in the code. I don't think that's needed to understand the code.
<SAMPLE>
Imports System.Xml
Imports System.Security
Imports System.Security.Cryptography
Imports System.Security.Cryptography.Xml
Imports System.Security.Cryptography.X509Certificates
Public Class Form1
Inherits System.Windows.Forms.Form
#Region " Windows Form Designer generated code "
...
#End Region
Private Sub SignButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SignButton.Click
' Generate a signing key.
'
Dim Key As New RSACryptoServiceProvider
' Create a new XML document.
'
Dim doc As New XmlDocument
' Format using white spaces.
'
doc.PreserveWhitespace = True
' Load the passed XML.
'
doc.Load(TextBox2.Text)
' Create a SignedXml object.
'
Dim signedXml As New SignedXml(doc)
' Add the key to the SignedXml document.
'
signedXml.SigningKey = Key
' Create a reference to be signed.
'
Dim reference As New Reference
reference.Uri = ""
' Add a transformation to the reference.
'
Dim trns As XmlDsigC14NTransform = New XmlDsigC14NTransform
reference.AddTransform(trns)
' Add an enveloped transformation to the reference.
'
Dim env As New XmlDsigEnvelopedSignatureTransform
reference.AddTransform(env)
' Add the reference to the SignedXml object.
'
signedXml.AddReference(reference)
' Add an RSAKeyValue KeyInfo (optional; helps recipient find key to validate).
'
Dim keyInfo As New KeyInfo
keyInfo.AddClause(New RSAKeyValue(CType(Key, RSA)))
signedXml.KeyInfo = keyInfo
' Compute the signature.
'
signedXml.ComputeSignature()
' Get the XML representation of the signature and save
' it to an XmlElement object.
'
Dim xmlDigitalSignature As XmlElement = signedXml.GetXml()
' Append the element to the XML document.
'
doc.DocumentElement.AppendChild(doc.ImportNode(xmlDigitalSignature, True))
If TypeOf doc.FirstChild Is XmlDeclaration Then
doc.RemoveChild(doc.FirstChild)
End If
' Show the signature
'
ToVerifyTextBox.Text = doc.OuterXml
End Sub
Private Sub SignWithCerButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SignWithCerButton.Click
' Variables
'
Dim bResult As Boolean = False
Dim pCertContext As IntPtr = IntPtr.Zero
Dim key As RSA = Nothing
Dim doc As XmlDocument = Nothing
Dim signedXml As SignedXml = Nothing
Dim reference As Reference = Nothing
Dim trns As XmlDsigC14NTransform = Nothing
Dim env As XmlDsigEnvelopedSignatureTransform = Nothing
Dim keyInfo As KeyInfo = Nothing
Dim xmlDigitalSignature As XmlElement = Nothing
Dim cert As X509Certificate2 = Nothing
Dim pass As SecureString = Nothing
' Generate a signing key from the subject certificate.
'
pass = New SecureString()
pass.AppendChar("p")
pass.AppendChar("a")
pass.AppendChar("s")
pass.AppendChar("s")
pass.AppendChar("w")
pass.AppendChar("o")
pass.AppendChar("r")
pass.AppendChar("d")
cert = New X509Certificate2(TextBox1.Text, pass)
key = cert.PrivateKey
' Create a new XML document.
'
doc = New XmlDocument
' Format using white spaces.
'
doc.PreserveWhitespace = True
' Load the passed XML.
'
doc.Load(TextBox2.Text)
' Create a SignedXml object.
'
signedXml = New SignedXml(doc)
' Add the key to the SignedXml document.
'
signedXml.SigningKey = key
' Create a reference to be signed.
'
reference = New Reference
reference.Uri = ""
' Add a transformation to the reference.
'
trns = New XmlDsigC14NTransform
reference.AddTransform(trns)
' Add an enveloped transformation to the reference.
'
env = New XmlDsigEnvelopedSignatureTransform
reference.AddTransform(env)
' Add the reference to the SignedXml object.
'
signedXml.AddReference(reference)
' Add an RSAKeyValue KeyInfo (optional; helps recipient find key to validate).
'
'keyInfo = New KeyInfo
'keyInfo.AddClause(New RSAKeyValue(CType(Key, RSA)))
'signedXml.KeyInfo = keyInfo
' Create a new KeyInfo object.
'
keyInfo = New KeyInfo()
' Load the certificate into a KeyInfoX509Data object
' and add it to the KeyInfo object.
keyInfo.AddClause(New KeyInfoX509Data(cert))
' Add the KeyInfo object to the SignedXml object.
signedXml.KeyInfo = keyInfo
' Compute the signature.
'
signedXml.ComputeSignature()
' Get the XML representation of the signature and save
' it to an XmlElement object.
'
xmlDigitalSignature = signedXml.GetXml()
' Append the element to the XML document.
'
doc.DocumentElement.AppendChild(doc.ImportNode(xmlDigitalSignature, True))
If TypeOf doc.FirstChild Is XmlDeclaration Then
doc.RemoveChild(doc.FirstChild)
End If
' Show the signature
'
ToVerifyTextBox.Text = doc.OuterXml
End Sub
Private Sub VerifyButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles VerifyButton.Click
' Create a new XML document.
'
Dim xmlDocument As New XmlDocument
' Format using white spaces.
'
xmlDocument.PreserveWhitespace = True
' Load the passed XML file into the document.
'
xmlDocument.LoadXml(ToVerifyTextBox.Text)
' Create a new SignedXml object and pass it the XML document class.
'
Dim signedXml As New SignedXml(xmlDocument)
' Find the "Signature" node and create a new XmlNodeList object.
'
Dim nodeList As XmlNodeList = xmlDocument.GetElementsByTagName("Signature", "https://www.w3.org/2000/09/xmldsig#")
' Load the signature node.
'
signedXml.LoadXml(CType(nodeList(0), XmlElement))
' Check the signature and show the result.
'
If signedXml.CheckSignature() Then
MessageBox.Show("Signature verified!")
Else
MessageBox.Show("Invalid signature!!!")
End If
End Sub
End Class
</SAMPLE>
I hope this helps.
Cheers,
Alex (Alejandro Campos Magencio)
Comments
- Anonymous
April 18, 2008
OH! Very good , I want it . Thanks :D - Anonymous
June 03, 2008
Hi,What i need to sign the same doc multiple times & then try to verify the same ? How would that work ?I tired to simply add one more signature to the signing part with a new key & try to get the same from the next node for verification.In this case the first signature fails but the second one passes. Any clue if wot im doing is right ? - Anonymous
March 25, 2009
Thanks for helping me on the way with my project!I've written a class for signing and verifying XML with C# .NET 1.1 using CAPICOM: http://blog.sallarp.com/2009/03/verify-xml-signatures-with-net-1-using-capicom/ - Anonymous
February 15, 2010
Thank you very much for you post. I found it very useful. - Anonymous
June 10, 2010
Hello,Hope you are still reading this. I really enjoyed the example. Got a question tough. How can I retrieve the X509Certificate from the signedXMl document ? I want to check also the attached certificate, not only the signature. I tried with GetElementsByTagName("X509Certificate"). This results in a nodelist of 1 element, but how to cast this or convert this to a X509Certificate object ? I want to match this to a list of allowed issuers.If you have any idea on this, please help me out.Best regards,Ronald - Anonymous
June 13, 2010
Sorry, I have no free time to attend this kind of requests. If you open a case with Microsoft Technical Support, we may be able to assist.Regards,Alex - Anonymous
October 01, 2015
Thanks Alex for the great example, really easy to follow and provided a solid base for an XML signing app I'm working on