Creating an enveloped XML signature

Your application should perform the following steps to create an enveloped XML signature using the toolkit.

Logging the user

Log in the user with the selected credentials.

user.login(credReader, <password>);

Logging the user

Instantiate a source for the keys and certificates using a com.entrust.toolkit.KeyAndCertificateSource object.

user.login(credReader, <password>);

Provide a signing key and verification certificate.

PrivateKey pk = user.getSigningKey();
X509Certificate cert = user.getVerificationCertificate();

Set the signing key and the verification certificate.

keySource.setSigningInfo(pk, cert);

Initializing the IXSIL library

Retrieve the init.properties file and initialize the IXSIL library.

iaik.ixsil.util.URI initProps = new URI(<init_properties_file_URI>);
IXSILInit.init(initProps);

Refer to the readme file for more information on editing the init.properties file.

etjava\examples\source\com\entrust\toolkit\examples\xml\xml_readme.html

Refer also to the Javadoc documentation of the following class.

iaik.ixsil.init.IXSILInit

Referencing the signed data

Specify the XML element in your document that is to be the parent of the <Signature> element.

String insertSignaturePositionHere = <XML_element_name>;

Create the XPath expression that specifies the position of the <Signature> element.

String xpath = null;
xpath = "(//" + insertSignatureHere + ")[1]";
Position signaturePosition = new Position(xpath, "", 0);
URI baseURI = new URI(uriTobeSigned);

Configuring a SOAP document signature

If you apply an XML digital signature to a SOAP document, retrieve a DOM representation of the document to be signed.

Document doc = DOMUtils.createDocumentFromXMLInstance(isURI, baseURI, DOMUtils.VALIDATION_YES_, noNamespaceSchemaLocation, schemaLocations);

See the following table for a description of each parameter.

Parameter

Description

​​ isURI

The input stream that you get by resolving the URI of the document source

baseURI

The URI that points to the XML document containing the XML signature.

DOMUtils.VALIDATION_YES_

Specifies that a validating parser should create the DOM document.

noNamespaceSchemaLocation

The schema for elements without a namespace prefix (if a validating parser creates the DOM document).

schemaLocations

Schemas for various namespaces (if a validating parser creates the DOM document).

Get the WS-Security namespace and prefix.

String wsSecNamespaceURI = IXSILInit.getInitProperty(IXSILConstants.INITPROP_URI_WS_SECURITY_);
String wsSecPrefix = IXSILInit.getInitProperty(IXSILConstants.INITPROP_NS_PREFIX_WS_SECURITY_);

Check for the existence of the SOAP Header.

Element root = doc.getDocumentElement();
String soapNsUri = root.getNamespaceURI();
NodeList nl = doc.getElementsByTagNameNS(soapNsUri, IXSILConstants.SOAP_HEADER_TAG_);
Element security = null;

Built a SOAP Header if not found.

Element header = doc.createElementNS(soapNsUri, root.getPrefix() + ":" + IXSILConstants.SOAP_HEADER_TAG_);
Node oldFirst = root.getFirstChild();
root.insertBefore(header, oldFirst);
security = doc.createElementNS(wsSecNamespaceURI, wsSecPrefix + ":" + IXSILConstants.WS_SECURITY_TAG_);
header.insertBefore(security, null);
root.setAttributeNS(IXSILConstants.NAMESPACE_URI_NAMESPACES_,IXSILConstants.NAMESPACE_PREFIX_NAMESPACES_ + wsSecPrefix, wsSecNamespaceURI);

Creating the signer

Create a Signer object, using the constructor that takes a Document instance.

Document doc = parser.parse(istrURI);
signer = new Signer(doc, baseURI, signaturePosition);

Use this constructor if your application has already parsed an existing XML source to a document and manipulated it, ensuring the toolkit does not repeat the document.

Selecting the canonicalization algorithm

Use the following class to specify the canonicalization algorithm for the signature.

iaik.ixsil.algorithms.CanonicalizationAlgorithmImplCanonicalXML

Create a new instance.

CanonicalizationAlgorithmImplCanonicalXML c14nAlg = new CanonicalizationAlgorithmImplCanonicalXML();

Set the algorithm URI.

c14nAlg.setURI(new URI("http://www.w3.org/TR/2000/WD-xml-c14n-20000907"));

Set the canonicalization algorithm.

signedInfo.setCanonicalizationAlgorithm(c14nAlg);

Selecting the signature algorithm

Specify and set the signature algorithm using the following classes.

iaik.ixsil.algorithms.SignatureAlgorithmImplDSA
iaik.ixsil.algorithms.SignatureAlgorithmImplRSA
iaik.ixsil.algorithms.SignatureAlgorithm

Instantiate a signature algorithm of the appropriate kind and set the corresponding URI.

SignatureAlgorithm signatureAlg = null ;
PrivateKey privatekey = keySource.getSigningKey();
if(privatekey.getAlgorithm().equals("DSA"))
{
signatureAlg = new SignatureAlgorithmImplDSA();
signatureAlg.setURI(new URI("http://www.w3.org/2000/09/xmldsig#dsa-sha1"));
}
else
{
signatureAlg = new SignatureAlgorithmImplRSA();
signatureAlg.setURI(new URI("http://www.w3.org/2000/09/xmldsig#rsa-sha1"));
}

Set the private key.

signatureAlg.setSignerKey(privatekey);

Set the algorithm.

signedInfo.setSignatureAlgorithm(signatureAlg);

Referencing the signed data

Configure references to the resources you want to sign and add them to the <SignedInfo> element.

SignerReference reference = signedInfo.createReference();

Set the URI to null so that the enveloped signature is over the entire XML document.

reference.setURI(new URI("") );

To sign a particular element of a SOAP message (or any message), instead of signing the entire XML document, use the following and pass in the ID attribute of the element to be signed.

URI uri = new URI(null, null, "", null, id);

Create an enveloped signature transform.

TransformImplEnvelopedSignature transform = new TransformImplEnvelopedSignature();

Set the transform's algorithm URI.

transform.setURI(new URI("http://www.w3.org/2000/09/xmldsig#enveloped-signature"));

Set the enveloped signature transform in reference to prevent the signing operation from signing the <Signature> element itself.

reference.insertTransformAt(transform, 0);

Create a digest algorithm.

DigestAlgorithmImplSHA1 digestAlg1 = new DigestAlgorithmImplSHA1();

Set the digest algorithm's URI.

digestAlg1.setURI(new URI("http://www.w3.org/2000/09/xmldsig#sha1"));

Set the digest algorithm.

reference.setDigestAlgorithm(digestAlg1);

Add the resource reference to the signature.

signedInfo.addReference(reference);

The <SignedInfo> element contains one or more references to the resources signed by the XML signature. This step configures and adds one reference to the XML signature. To add more references, repeat the step.

Selecting the digest algorithm

Create a new instance of the digest algorithm.

DigestAlgorithmImplSHA1 digestAlg1 = new DigestAlgorithmImplSHA1();

Set the URI of the digest algorithm.

digestAlg1.setURI(new URI("http://www.w3.org/2000/09/xmldsig#sha1"));

Set the digest algorithm.

firstRef.setDigestAlgorithm(digestAlg1);

Add the resource reference to the signature.

signedInfo.addReference(firstRef);

Adding key information

Instantiate a key manager.

Document signatureDOMDoc = signer.toDocument();
KeyManagerImpl keyManager = new KeyManagerImpl(signatureDOMDoc);

Create and configure a KeyInfo provider for the X509Data clause.

KeyProviderImplX509Data keyProviderX509Data = new KeyProviderImplX509Data(signatureDOMDoc);

Include the user's verification certificate in the <KeyInfo> element.

X509Certificate certificate = keySource.getVerificationCertificate();
X509Data x509 = new X509Data();
x509.insertHintAt(certificate, 0) ;

Include the user's distinguished name in the <KeyInfo> element.

X509SubjectName x509Name = new X509SubjectName((Name) certificate.getSubjectDN());
x509.insertHintAt(x509Name, 0);
keyProviderX509Data.insertX509DataAt(x509, 0);

Create and configure a KeyInfo provider for the KeyValue clause.

KeyProviderImplKeyValue keyProviderKeyValue = new KeyProviderImplKeyValue(signatureDOMDoc);
keyProviderKeyValue.setVerifierKey(certificate.getPublicKey());

Add any of these KeyInfo providers.

keyManager.addKeyProvider(keyProviderKeyValue);
keyManager.addKeyProvider(keyProviderX509Data);

Set the signature's key manager.

signer.getSignature().setKeyManager((SignerKeyManager) keyManager);

Adding the KeyInfo element

If your application supports non-repudiation of XML digital signatures, create a reference for the <KeyInfo> element.

SignerReference ref = signedInfo.createReference();

Identify the <KeyInfo> element reference with a URI.

String keyInfoId = keyManager.getId();
ref.setURI(new URI(null, null, null, null, keyInfoId));

Add the <KeyInfo> element reference to the resources to be signed.

signedInfo.addReference(ref);

Generating the signature

Calculate the signature value.

signer.getSignature().sign();

Return the signed document to complete the procedure.

return signer.toDocument();