PxPlus User Forum

Twitter Twitter Twitter

Author Topic: Sign XML Documents with Digital Signatures  (Read 1777 times)

HendersonS

  • Gold Member
  • ****
  • Posts: 59
    • View Profile
Sign XML Documents with Digital Signatures
« on: February 18, 2024, 04:05:16 PM »
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: [Select]
''' <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
« Last Edit: February 18, 2024, 04:58:24 PM by HendersonS »

Loren Doornek

  • Gold Member
  • ****
  • Posts: 85
    • View Profile
Re: Sign XML Documents with Digital Signatures
« Reply #1 on: February 19, 2024, 12:57:33 PM »
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

  • Gold Member
  • ****
  • Posts: 59
    • View Profile
Re: Sign XML Documents with Digital Signatures
« Reply #2 on: February 19, 2024, 08:23:19 PM »
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: [Select]
<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>

Mike King

  • Diamond Member
  • *****
  • Posts: 3817
  • Mike King
    • View Profile
    • BBSysco Consulting
Re: Sign XML Documents with Digital Signatures
« Reply #3 on: February 20, 2024, 07:42:33 AM »
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.
Mike King
President - BBSysco Consulting
eMail: mike.king@bbsysco.com

HendersonS

  • Gold Member
  • ****
  • Posts: 59
    • View Profile
Re: Sign XML Documents with Digital Signatures
« Reply #4 on: February 20, 2024, 04:47:02 PM »
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?
« Last Edit: February 20, 2024, 09:10:26 PM by HendersonS »

Loren Doornek

  • Gold Member
  • ****
  • Posts: 85
    • View Profile
Re: Sign XML Documents with Digital Signatures
« Reply #5 on: February 21, 2024, 07:03:17 PM »
Here's a simple example of creating a signature hash for an XML document, based on a Wikipedia example.  But, this only creates the signature and does not encrypt the signature data using RSA, which is what the XML signing requires.  To complete the process, you would need to finish building the required XML (most of which was included in your example in the <Signature> segment), and then create an RSA-encrypted signature value for that segment.  I don't know of any method of using RSA encryption directly within PXPlus, but maybe Mike can comment on that.  Mikes suggestion of using the XMLSEC utility might be the only method of handling the RSA part.


-;list
0010 BEGIN
0020 LET inv$=XML(ADD "Marge Simpson" TO inv$,KEY="Client")
0030 LET inv$=XML(ADD "847.63" TO inv$,KEY="Amount")
0040 LET inv$=XML(ADD inv$ TO $$,KEY="Invoice")
0050 LET sig$=CVS(HSH(inv$,256),"ASCII:BASE64")
0060 LET xml$=XML(ADD sig$ TO inv$,KEY="Signature",OPT="xmlns=""http://www.w3.org/2000/09/xmldsig#""")
0070 PRINT xml$
-;
-;run

<Invoice>
 <Client>Marge Simpson</Client>
 <Amount>847.63</Amount>
</Invoice>
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">G9Q1/Lu96dgOVNd3ZChqZLCBUDgIPuAivTwVIngey2U=</Signature>
-;

HendersonS

  • Gold Member
  • ****
  • Posts: 59
    • View Profile
Re: Sign XML Documents with Digital Signatures
« Reply #6 on: February 23, 2024, 12:43:19 PM »
Loren, thanks for your demonstration,

so far I have not been able to install xmlsec on Windows, and I have not been able to find a solution with pxplus either, so I will have to make some program in C# or another language to invoke it from pxplus, since I do not see a solution with pxplus.