When curating APIs, creating your API Program, many of you deal with XML documents of some form or another. Either you have API Proxies that connect to XML APIs and act as facades, exposing a more developer-friendly JSON interface, or you are using Apigee Edge to pass-through XML APIs, in order to obtain analytics information, rate limiting, and so on.
In some cases, people use Digital Signatures on XML payloads. Now we know about JWT - this is a way to sign JSON payloads. Apigee Edge has built-in policies that generate signed JWT, and verify signatures on JWT.
We are now offering XML analogues to those policies.
The Java callout for XML DSIG provides the ability to sign arbitrary XML documents with an RSA Private Key, or to validate signatures on an XML Document using a public key.
It's easy to use out of the box. Here's a configuration you can use to sign any XML document:
<JavaCallout name='Java-XMLDSIG-Sign'> <Properties> <Property name='source'>message.content</Property> <Property name='output-variable'>output</Property> <Property name='private-key'>{my_private_key}</Property> <Property name='private-key-password'>{my_private_key_password}</Property> </Properties> <ClassName>com.google.apigee.edgecallouts.xmldsig.Sign</ClassName> <ResourceURL>java://edge-xmldsig-1.0.1.jar</ResourceURL> </JavaCallout>
And here's a configuration to validate an XML DSIG:
<JavaCallout name='Java-XMLDSIG-Validate'> <Properties> <Property name='source'>message.content</Property> <Property name='public-key'>{my_public_key}</Property> </Properties> <ClassName>com.google.apigee.edgecallouts.xmldsig.Validate</ClassName> <ResourceURL>java://edge-xmldsig-1.0.1.jar</ResourceURL> </JavaCallout>
The result of the signing is a new XML document with a Signature element. The result of validating is a boolean: true/false indicating whether the signature was valid given the provided public key.
Try it for your XML signatures and let me know how it goes!
I am new to Apigee and need some clarification on XMLDSIG. What to put as the value of properties "private-key" and "public-key", will it be keystore/truststore name or alias within that.
Ahh, that'a a good question. I should have mentioned that.
This is a Java callout; officially, it's not part of the apigee Edge product. It's an extension.
Th Java callout is not able to read from the keystore or truststore that is used internally by Apigee Edge.
As a result, the keys used by this XMLDSIG callout must be specified in PKCS8 PEM format. They look like this:
-----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxRbBophgmMU8OlwaoDZ/ NHnghjjYRpG+4pC6g5PofcMxJUXKdgCb16vrTpdG/52hbT/XfeYaOorE718zaJlJ t7l4+LEmBIxGicHHl4OvrEliKnIrcc0B+JIdRz034A2KW8ijad7Axjsq43N92Ypc renVg4WPLPa3ddHvE/zIuN7W3FivMflflolsWjlXO7YRUfLSWMzOI4Ewf1eidQQX YIyn1zMrYGUhAgWydXmVy6D62tUPDY1eqE9hxCaBpevUCdWBT2jmS33Ec/WH2LDd LpiHkPT4BqXlJVrqqJL7e58GQxgs0blGjwjs19DwJPss2asqO3qyq0TgCMeDvhB7 pwIDAQAB -----END PUBLIC KEY-----
And
-----BEGIN RSA PRIVATE KEY----- MIIEpAIBAAKCAQEAxRbBophgmMU8OlwaoDZ/NHnghjjYRpG+4pC6g5PofcMxJUXK dgCb16vrTpdG/52hbT/XfeYaOorE718zaJlJt7l4+LEmBIxGicHHl4OvrEliKnIr cc0B+JIdRz034A2KW8ijad7Axjsq43N92YpcrenVg4WPLPa3ddHvE/zIuN7W3Fiv MflflolsWjlXO7YRUfLSWMzOI4Ewf1eidQQXYIyn1zMrYGUhAgWydXmVy6D62tUP ... /KewEZECgYA0HY8BhKxnDPD3txK4cNObNOPCrAEGo1KCYJAVr0EU3CWkza8ee/iF fUf3BzKFG6xOtC7H6OmlXNsXnxy5nFSqlmcd7xZcx2/tve/FKb7sF8tn9fT+CVWs NI+u1drdYnQXy8CFV+7+OjSFblDQO7qBp1qQbVbT0DFYETBKojYvNw== -----END RSA PRIVATE KEY-----
You have some options for specifying the keys.
<JavaCallout name='Java-XMLDSIG-Validate'> <Properties> <Property name='source'>message.content</Property> <Property name='public-key'> -----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxRbBophgmMU8OlwaoDZ/ NHnghjjYRpG+4pC6g5PofcMxJUXKdgCb16vrTpdG/52hbT/XfeYaOorE718zaJlJ t7l4+LEmBIxGicHHl4OvrEliKnIrcc0B+JIdRz034A2KW8ijad7Axjsq43N92Ypc renVg4WPLPa3ddHvE/zIuN7W3FivMflflolsWjlXO7YRUfLSWMzOI4Ewf1eidQQX YIyn1zMrYGUhAgWydXmVy6D62tUPDY1eqE9hxCaBpevUCdWBT2jmS33Ec/WH2LDd LpiHkPT4BqXlJVrqqJL7e58GQxgs0blGjwjs19DwJPss2asqO3qyq0TgCMeDvhB7 pwIDAQAB -----END PUBLIC KEY----- </Property> </Properties> <ClassName>com.google.apigee.edgecallouts.xmldsig.Validate</ClassName> <ResourceURL>java://edge-xmldsig-1.0.1.jar</ResourceURL> </JavaCallout>
<AssignMessage name='AM-1'> <AssignVariable> <Name>publickey</Name> <Value> -----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxRbBophgmMU8OlwaoDZ/ NHnghjjYRpG+4pC6g5PofcMxJUXKdgCb16vrTpdG/52hbT/XfeYaOorE718zaJlJ t7l4+LEmBIxGicHHl4OvrEliKnIrcc0B+JIdRz034A2KW8ijad7Axjsq43N92Ypc renVg4WPLPa3ddHvE/zIuN7W3FivMflflolsWjlXO7YRUfLSWMzOI4Ewf1eidQQX YIyn1zMrYGUhAgWydXmVy6D62tUPDY1eqE9hxCaBpevUCdWBT2jmS33Ec/WH2LDd LpiHkPT4BqXlJVrqqJL7e58GQxgs0blGjwjs19DwJPss2asqO3qyq0TgCMeDvhB7 pwIDAQAB -----END PUBLIC KEY-----</Value> </AssignVariable> </AssignMessage>
Thanks Dino,
This was really helpful. I tried and its working as expected however I was wondering if we can read the key/cert details from KeyStore/TrustStore respectively. In my case there will be multiple consumers so there will be multiple certificates for validation.