Main Board > Programming

Sign XML Documents with Digital Signatures

(1/2) > >>

HendersonS:
Hello everyone,
recently we are working on web services that use digitally signed xml files for validation, these xml files must be signed with digital certificates (.P12 files), does anyone have experience doing this? Or can you guide us how to do this in Pvx Plus? Any idea is welcome, thank you very much in advance.

Below is some example code in VB.NET. Any idea how we can replicate it in pxplus?



--- Code: ---''' <summary>
 ''' Method for signing XML with digital certificate (*.p12)
 ''' </summary>
 ''' <param name="xmlDoc"> document to sign </param>
 ''' <param name="pathCert">location of certificate to use for signing </param>
 ''' <param name="passCert">digital certificate password</param>
 ''' <returns>Digitally signed XML</returns>
 Private Function Signed (ByVal xmlDoc As XmlDocument, ByVal pathCert As String, ByVal
passCert As String) As XmlDocument
 Try
 If Not File.Exists(pathCert) Then Throw New Exception("The signing certificate does not exist")
 Dim cert = New X509Certificate2(pathCert, passCert, X509KeyStorageFlags.Exportable)
 Dim exportedKeyMaterial = cert.PrivateKey.ToXmlString(True)
 Dim key = New RSACryptoServiceProvider(New CspParameters(24))
 key.PersistKeyInCsp = False
 key.FromXmlString(exportedKeyMaterial)
 Dim signedXml As SignedXml = New SignedXml(xmlDoc)
  signedXml.SigningKey = key
  signedXml.SignedInfo.SignatureMethod =
 "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"
  Dim reference As Reference = New Reference()
  reference.AddTransform(New XmlDsigEnvelopedSignatureTransform())
  reference.DigestMethod = "http://www.w3.org/2001/04/xmlenc#sha256"
  reference.Uri = ""
  signedXml.AddReference(reference)
  Dim keyInfo As KeyInfo = New KeyInfo()
  keyInfo.AddClause(New KeyInfoX509Data(cert))
  signedXml.KeyInfo = keyInfo
  signedXml.ComputeSignature()
  Dim xmlDigitalSignature As XmlElement = signedXml.GetXml()
  xmlDoc.DocumentElement.AppendChild(xmlDoc.ImportNode(xmlDigitalSignature, True))
  Return xmlDoc
  Catch ex As Exception
  Throw ex
  End Try
 End Function
--- End code ---

Loren Doornek:
You can do this in PXPlus using the HSH() function, and possibly the CVS() function to convert to Base64. 

I've worked on several web interfaces that require some sort of digital signature as part of the data (usually, as part of the HTTP data sent).  They are all very similar:  Take some chunk of data or a concatenation of various data fields, create a hash of that data using the private key, convert the hashed value to base64, then include the hashed value (signature) in the data being submitted.

The recipient also needs to know the public key which needs to be used to decrypt the signature.  In looking over the XML signing documentation, it appears that you must include the public key as a field in the XML data.  (For websites, you generally provide some sort of username/login, which the website then uses internally to retrieve the decryption key associated with your account)

The HSH function in PXPlus will allow you to encrypt the data in various formats using various keys (certificates) (https://manual.pvxplus.com/PXPLUS/functions/hsh.htm#format_1)

The CVS function can be used to convert the signature to base64 encoding (eg:  sig$=CVS(mydata$,"ASCII:BASE64")  ), or you can use the *web/base64 utility.

If you aren't able to get it working, let me know and I can try to generate a short example.

HendersonS:
Loren thanks for yor reply

Below is the structure that the signature node should have within the xml, I have no experience in building these signatures. Maybe you can show me some example code to do it.


--- Code: ---<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
 <SignedInfo>
<CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/RECxml-c14n-20010315" />
<SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsigmore#rsa-sha256" />
<Reference URI="">
 <Transforms>
 <Transform Algorithm="http://www.w3.org/2000/09/xmldsig#envelope d-signature" />
 </Transforms>
 <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
 <DigestValue>Atr9H7DiGlxrQOFII/hFihsL6ACiwe47Oo93tgtuera=</DigestValue>
</Reference>
</SignedInfo>
 <SignatureValue>gQyXO0FFDGIITESTpP5xZjLIRtv/Q7/ixe1lNDLDA5aw...</SignatureValue>
<KeyInfo>
 <X509Data>
<X509Certificate>DGIITESTBFagAwIBAgIIInYGQUX9q0IwDQYJKoZIhvcNAQ...</X509Certificate>
 </X509Data>
 </KeyInfo>
</Signature>
--- End code ---

Mike King:
I would probably use XMLSEC (xmlsec1) to do this from command line as it is available on both windows and Linux and there is fairly extensive documentation available at:

http://sgros.blogspot.com/2013/01/signing-xml-document-using-xmlsec1.html

Here is the command documentation:

https://www.mankier.com/1/xmlsec1

While PxPlus logic could be used directly; by using a standard package like xmlsec1, should you have any issues the company receiving the XML may have examples.

HendersonS:
Thanks Mike for your instructions.

If I understood correctly, you mean that I can invoke this tool from pxplus? And just in case I take another route to do it with pxplus, is there any utility to extract the private key from a .pem?

Navigation

[0] Message Index

[#] Next page

Go to full version