web stats
Web Service sender and WSSE - Mirth Community

Go Back   Mirth Community > Mirth Connect > Support

Thread Tools Display Modes
Old 05-16-2019, 01:07 PM
mitch_nchin mitch_nchin is offline
Mirth Newb
Join Date: Nov 2015
Posts: 18
mitch_nchin is on a distinguished road
Default Web Service sender and WSSE

We need to digitally sign a timestamp within a SOAP message. Is this doable from within Mirth? We have the SSH extension but I don't know whether it handles this.


Here's an example message we've been provided; presumably it is the Signature tag that we'll need to generate based on the message's timestamp:
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:urn="urn:cdc:iisb:2011">
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<ds:Signature Id="SIG-D8234953C823AFAE2415536312716865" xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-excc14n#">
<ec:InclusiveNamespaces PrefixList="soap urn" xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#"/>
<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsasha1"/>
<ds:Reference URI="#TS-D8234953C823AFAE2415536312715641">
<ds:Transform Algorithm="http://www.w3.org/2001/10/xmlexc-c14n#">
<ec:InclusiveNamespaces PrefixList="wsse soap urn" xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#"/>
<dsigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<dsigestValue>Content Redacted
<ds:SignatureValue>Content Redacted</ds:SignatureValue>
<ds:KeyInfo Id="KI-D8234953C823AFAE2415536312716723">
<wsse:SecurityTokenReference wsu:Id="STRD8234953C823AFAE2415536312716744">
<wsse:KeyIdentifier EncodingType="http://docs.oasisopen.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary" ValueType="http://docs.oasisopen.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3">
Content Redacted
<wsu:Timestamp wsu:Id="TS-D8234953C823AFAE2415536312715641">
<urn:username>Content Redacted – User name provided by DOH</urn:username>
<urnassword>Content Redacted – Password provided by DOH</urnassword>
<urn:facilityID>Content Redacted – Facility ID provided by OHP</urn:facilityID>
<urn:hl7Message>Content Redacted – Message content information available DOH

Reply With Quote
Old 05-17-2019, 07:27 AM
agermano agermano is offline
Mirth Guru
Join Date: Apr 2017
Location: Indiana, USA
Posts: 1,176
agermano is on a distinguished road

It's likely doable. Most things are.

I assume you meant the SSL (not SSH) extension, and as far as I know that is only for setting up encrypted tunnels, not for digital signatures.

I'm afraid I don't know enough about your requirements to give you a definite answer.
Reply With Quote
Old 05-17-2019, 01:46 PM
mitch_nchin mitch_nchin is offline
Mirth Newb
Join Date: Nov 2015
Posts: 18
mitch_nchin is on a distinguished road

Yes, SSL extension. Thank you so much. Is anyone else able to offer a definite answer?
Reply With Quote
Old 05-17-2019, 02:08 PM
agermano agermano is offline
Mirth Guru
Join Date: Apr 2017
Location: Indiana, USA
Posts: 1,176
agermano is on a distinguished road

You don't have the requirements of what you're trying to do?
Reply With Quote
Old 05-20-2019, 06:07 AM
mitch_nchin mitch_nchin is offline
Mirth Newb
Join Date: Nov 2015
Posts: 18
mitch_nchin is on a distinguished road

The requirement is to apply a digital signature to fields including the timestamp, as described in WSSE, and include it in the SOAP message.

As an aside, when you cannot actually be helpful, there is absolutely no need to post.
Reply With Quote
Old 07-04-2019, 02:14 PM
sterk sterk is offline
What's HL7?
Join Date: Jul 2019
Posts: 1
sterk is on a distinguished road

Hi mitch_nchin

Did you find a solution to sign a timestamp ?

I have the same problem, add a signed timestamp in SOAP WSS request.

Thanks for help
Reply With Quote
Old 07-08-2019, 08:09 AM
narupley's Avatar
narupley narupley is offline
Mirth Employee
Join Date: Oct 2010
Posts: 7,126
narupley is on a distinguished road

Just an FYI we did add this ability with a new commercial extension in 3.6, the Interoperability Connector Suite. The NHIN-compliant assertion and timestamp are both automatically signed, and it integrates with the SSL Manager so you can choose which local cert/keypair you want to sign with.

Otherwise, I would look into a third-party library like CryptoJS. I think you should be able to create signatures and set them in the SOAP header with that.
Step 1: JAVA CACHE...DID YOU CLEAR ...wait, ding dong the witch is dead?

Nicholas Rupley
Work: 949-237-6069
Always include what Mirth Connect version you're working with. Also include (if applicable) the code you're using and full stacktraces for errors (use CODE tags). Posting your entire channel is helpful as well; make sure to scrub any PHI/passwords first.

- How do I foo?
- You just bar.
Reply With Quote
Old 10-24-2019, 07:31 AM
skirby skirby is offline
What's HL7?
Join Date: Oct 2019
Posts: 1
skirby is on a distinguished road

Hi folks,

I’m not sure if you found a solution that works for you yet, but you should be able to implement the functionality you’re describing here using the Java XML-DSig API, which is available pretty much out of the box with commercial and open source java implementations (and accessible via Mirth Connect). That message envelop you initially included looks strikingly similar to the requirements defined by WAIIS/OneHealthPort, which I think I ended up implementing something like:

// Generate our dynamic message values
var timestampId = UUIDGenerator.getUUID();
var createdTimestamp = new Date().toISOString();
var expiresTimestamp = new Date((new Date()).getTime() + 1000*10).toISOString();
var hl7Message = xmlToHL7(msg);

var soapEnvelope = "<soap:Envelope xmlns:soap=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:urn=\"urn:cdc:iisb:2011\">" +
					"<soap:Header>" +
						"<wsse:Security xmlns:wsse=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd\" xmlns:wsu=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd\">" +
							"<wsu:Timestamp wsu:Id=\"" + timestampId + "\">" +
								"<wsu:Created>" + createdTimestamp + "</wsu:Created>" +
								"<wsu:Expires>" + expiresTimestamp + "</wsu:Expires>" +
							"</wsu:Timestamp>" +
						"</wsse:Security>" +
					"</soap:Header>" +
					"<soap:Body>" +
						"<urn:submitSingleMessage>" +
							"<urn:username>username</urn:username>" +
							"<urn:password>password</urn:password>" +
							"<urn:facilityID>facility</urn:facilityID>" +
							"<urn:hl7Message><![CDATA[" + hl7Message +"]]></urn:hl7Message>" +
						"</urn:submitSingleMessage>" +
					"</soap:Body>" +
var soapString = new java.lang.String(soapEnvelope);

// Build our XML DOM for signature
var documentBuilderFactory = javax.xml.parsers.DocumentBuilderFactory.newInstance();
var document = documentBuilderFactory.newDocumentBuilder().parse(new java.io.ByteArrayInputStream(soapString.getBytes("utf-8")));

// Configure Digital Signature utilities for required crypto operations
var xmlDsigFactory = javax.xml.crypto.dsig.XMLSignatureFactory.getInstance("DOM");
var parameterSpec = new javax.xml.crypto.dsig.spec.ExcC14NParameterSpec();

var reference = xmlDsigFactory.newReference
	"#" + timestampId,
	xmlDsigFactory.newDigestMethod(javax.xml.crypto.dsig.DigestMethod.SHA1, null),
	java.util.Collections.singletonList(xmlDsigFactory.newTransform("http://www.w3.org/2001/10/xml-exc-c14n#", parameterSpec)),
	null, //type
	null //id

var signedInfo = xmlDsigFactory.newSignedInfo
	xmlDsigFactory.newSignatureMethod(javax.xml.crypto.dsig.SignatureMethod.RSA_SHA1, null),

// Fetch our certificate and key
var certificate;

	var inputStream = new java.io.FileInputStream(“/path/to/your/cert”);
	var certificateFactory = java.security.cert.CertificateFactory.getInstance("X.509");
	certificate = certificateFactory.generateCertificate(inputStream);
	if (inputStream != null)

var privateKey;

var keyFactory = java.security.KeyFactory.getInstance("RSA");
var keySpec = new java.security.spec.PKCS8EncodedKeySpec(java.nio.file.Files.readAllBytes(new java.io.File(“/path/to/your/pkcs8”).toPath()));
privateKey = keyFactory.generatePrivate(keySpec);

// Generate the KeyInfo for our signature
var keyInfoFactory = xmlDsigFactory.getKeyInfoFactory();
var x509Content = new java.util.ArrayList();
var x509Data = keyInfoFactory.newX509Data(x509Content);
var keyInfo = keyInfoFactory.newKeyInfo(java.util.Collections.singletonList(x509Data));

// Sign the document (timestamp element)
var timestampElement = document.getElementsByTagNameNS("http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd", "Timestamp").item(0);
var securityElement = document.getElementsByTagNameNS("http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd", "Security").item(0);
var domSignContext = new javax.xml.crypto.dsig.dom.DOMSignContext(privateKey, securityElement);
domSignContext.setIdAttributeNS(timestampElement,"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd", "Id");
var xmlSignature = xmlDsigFactory.newXMLSignature(signedInfo, keyInfo);

// Define any formatting preferences get the signed document as a string
var transformerFactory = javax.xml.transform.TransformerFactory.newInstance();
var transformer = transformerFactory.newTransformer();
transformer.setOutputProperty(javax.xml.transform.OutputKeys.OMIT_XML_DECLARATION, "yes");
var stringWriter = new java.io.StringWriter();
transformer.transform(new javax.xml.transform.dom.DOMSource(document), new javax.xml.transform.stream.StreamResult(stringWriter));

channelMap.put("soapMessage", stringWriter.toString());
Obviously, you would want to adapt the above code to your specific use-case/requirements (transforms, canonicalization methods, keyinfo types, etc.), but it ought to provide some sense of how you could leverage the provided XML-DSig utilities to get it done. The transformer above could potentially operate as a destination transformer, with a source connector that polls files, or gets hl7v2 messages over MLLP, etc. One drawback is that you don't get to leverage the fancy Mirth features that come from WDSL-generated SOAP Envelopes in the destination connector (the example above then puts the message body to the channel map, which then makes it available to an HTTP Sender which is manually configured to invoke the expected SOAP operation). There's an old how-to on the Java dsig API here: https://www.oracle.com/technical-res...ature-api.html

Fortunately I don't think much has changed in there since 2007...
Reply With Quote
Old 11-15-2019, 01:08 PM
mitch_nchin mitch_nchin is offline
Mirth Newb
Join Date: Nov 2015
Posts: 18
mitch_nchin is on a distinguished road

Just seeing this. THANK YOU skirby!!
Reply With Quote

wsse ws security

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump

All times are GMT -8. The time now is 03:10 AM.

Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2020, vBulletin Solutions, Inc.
Mirth Corporation