Create an enveloping signature using a DSA key
Use this example to digitally sign an XML document with a DSA key, producing an enveloping signature that guarantees the document has not been tampered with.
An enveloping signature wraps the signed content inside the
Signature element, keeping the data and signature together in a
single output file. This example uses the DSA-SHA256 algorithm, which is the
recommended algorithm for DSA digital signatures.
You can use the sample content provided in XML document (unsigned) for the purpose of testing the code. Copy the content to a file named "MyDocument.xml" in a directory where you test the sample code.
The sample code signs the XML document with a DSA private key named DSAKey.pem. Before running the example, generate the key with OpenSSL and copy it to the directory where you will run the sample code.
- Generate the DSA parameters:
The valueopenssl dsaparam -out DSAparam.pem 20482048specifies the key size in bits. - Generate the private key and save it to DSAKey.pem:
openssl gendsa -out DSAKey.pem DSAparam.pem
All keys or certificates in PEM or DER format were created with the OpenSSL tool. For information on how the OpenSSL tool works, refer to the openssl (external link) documentation.
Copy DSAKey.pem to the directory where you will run the sample code.
IMPORT xml
MAIN
DEFINE doc xml.DomDocument
DEFINE sig xml.Signature
DEFINE key xml.CryptoKey
DEFINE index INTEGER
DEFINE objInd INTEGER
# Create DomDocument object
LET doc = xml.DomDocument.Create()
# Notice that whitespaces are significant in cryptography,
# therefore it is recommended to remove unnecessary ones
CALL doc.setFeature("whitespace-in-element-content",FALSE)
TRY
# Load document to be signed
CALL doc.load("MyDocument.xml")
# Create DSA key and load it from file
LET key = xml.CryptoKey.Create(
"http://www.w3.org/2009/xmldsig11#dsa-sha256")
CALL key.loadPEM("DSAKey.pem")
# Create signature object with the key to use
LET sig = xml.Signature.Create()
CALL sig.setKey(key)
# Create an object inside the signature to envelop the root node
LET objInd = sig.createObject()
# Set the object id to get a reference
CALL sig.setObjectId(objInd,"data")
# Copy the enveloping node from the document
CALL sig.appendObjectData(objInd,doc.getDocumentElement())
# Set the reference to be signed on the object node.
# In our case, the object node with attribute 'data'
LET index = sig.createReference("#data",
"http://www.w3.org/2001/04/xmlenc#sha256")
# Set canonicalization method on the enveloping object to be signed.
CALL sig.appendReferenceTransformation(index,
"http://www.w3.org/2001/10/xml-exc-c14n#")
# Compute enveloping signature
CALL sig.compute(NULL)
# Retrieve signature document
LET doc=sig.getDocument()
# Save signature on disk
CALL doc.setFeature("format-pretty-print",TRUE)
CALL doc.save("MyDocumentEnvelopingSignature.xml")
CATCH
DISPLAY "Unable to create an enveloping signature :",status
END TRY
END MAIN
For an example of the output produced by this code, see XML document (signed with DSA key).