Digital Signature on Oracle BPEL flow
Lately I created a Java code based on some blogs and forums
what could found. This code is used into BPEL flow and it has some development premises:
- The file used for sign a XML file has the exclusive JKS-Java KeyStore format;
- The file used needs be posted on SOA Server (“${WEBLOGIC_DOMAIN_HOME}/security” folder). You can change the target folder for your codification, but you need modify this sample code in one exclusive point;
- The model for signature used is the X509 Signature on RSA SHA-1 Base64;
☛ Tip: This sample declare all path for java classes used, but if you want to define it in your BPEL code using follow syntax <bpelx:exec import="java.lang.String"/>, for your understanding see the document http://docs.oracle.com/cd/E25178_01/dev.1111/e10224/bp_java.htm#BGBEEEFB.
Defining Java Embedding code
/*
Digital Signature
Algorithm (DSA)
Created by Eduardo
Leite at 17-dec-2013
*/
try{
java.lang.String JKSFile
=
(java.lang.String)getVariableData("vKeyStoreFile");
java.lang.String JKSAlias
=
(java.lang.String)getVariableData("vKeyStoreAlias");
java.lang.String JKSPassword
=
(java.lang.String)getVariableData("vKeyStorePassword");
java.lang.String XMLinput
=
(java.lang.String)getVariableData("vXMLContent");
//Convert String to XMLDocument
javax.xml.parsers.DocumentBuilderFactory dbFactory =
javax.xml.parsers.DocumentBuilderFactory.newInstance();
javax.xml.parsers.DocumentBuilder dBuilder =
dbFactory.newDocumentBuilder();
oracle.xml.parser.v2.XMLDocument doc =
(oracle.xml.parser.v2.XMLDocument)dBuilder.parse(new
org.xml.sax.InputSource(new java.io.StringReader(XMLinput)));
String
providerName = System.getProperty("jsr105Provider",
"org.jcp.xml.dsig.internal.dom.XMLDSigRI");
javax.xml.crypto.dsig.XMLSignatureFactory fac =
javax.xml.crypto.dsig.XMLSignatureFactory.getInstance("DOM",
(java.security.Provider) Class.forName(providerName).newInstance());
javax.xml.crypto.dsig.DigestMethod digestMethod =
fac.newDigestMethod(javax.xml.crypto.dsig.DigestMethod.SHA1, null);
javax.xml.crypto.dsig.Transform transform =
fac.newTransform(javax.xml.crypto.dsig.Transform.ENVELOPED,
(javax.xml.crypto.dsig.spec.TransformParameterSpec) null);
javax.xml.crypto.dsig.Reference reference =
fac.newReference("", digestMethod,
java.util.Collections.singletonList(transform), null, null);
javax.xml.crypto.dsig.SignatureMethod signatureMethod =
fac.newSignatureMethod(javax.xml.crypto.dsig.SignatureMethod.RSA_SHA1,
null);
javax.xml.crypto.dsig.CanonicalizationMethod canonicalizationMethod =
fac.newCanonicalizationMethod(javax.xml.crypto.dsig.CanonicalizationMethod.EXCLUSIVE,
(javax.xml.crypto.dsig.spec.C14NMethodParameterSpec) null);
//
Create the SignedInfo
javax.xml.crypto.dsig.SignedInfo si
= fac.newSignedInfo(canonicalizationMethod, signatureMethod,
java.util.Collections.singletonList(reference));
// Load
the KeyStore and get the signing key and certificate.
//java.security.KeyStore ks = java.security.KeyStore.getInstance(
"jks" );
java.security.KeyStore ks =
java.security.KeyStore.getInstance(java.security.KeyStore.getDefaultType());
ks.load( new java.io.FileInputStream( "security/" + JKSFile ),
JKSPassword.toCharArray());
java.security.KeyStore.PrivateKeyEntry keyEntry =
(java.security.KeyStore.PrivateKeyEntry) ks.getEntry
( JKSAlias, new java.security.KeyStore.PasswordProtection(
JKSPassword.toCharArray()));
java.security.cert.X509Certificate cert = (java.security.cert.X509Certificate)
keyEntry.getCertificate();
//
Create the KeyInfo containing the X509Data.
javax.xml.crypto.dsig.keyinfo.KeyInfoFactory kif =
fac.getKeyInfoFactory();
java.util.List x509Content = new java.util.ArrayList();
x509Content.add(cert.getSubjectX500Principal().getName());
x509Content.add(cert);
javax.xml.crypto.dsig.keyinfo.X509Data xd =
kif.newX509Data(x509Content);
javax.xml.crypto.dsig.keyinfo.KeyInfo ki =
kif.newKeyInfo(java.util.Collections.singletonList(xd));
javax.xml.crypto.dsig.dom.DOMSignContext dsc = new
javax.xml.crypto.dsig.dom.DOMSignContext(keyEntry.getPrivateKey(),
doc.getDocumentElement());
//
Create the XMLSignature, but don't sign it yet.
javax.xml.crypto.dsig.XMLSignature signature = fac.newXMLSignature(si,
ki);
//
Marshal, generate, and sign the enveloped signature.
signature.sign(dsc);
//
Transform XMLDocument to String
javax.xml.transform.TransformerFactory
tf = javax.xml.transform.TransformerFactory.newInstance();
javax.xml.transform.Transformer
transformer;
transformer =
tf.newTransformer();
java.io.StringWriter writer = new java.io.StringWriter();
transformer.transform(new javax.xml.transform.dom.DOMSource(doc), new
javax.xml.transform.stream.StreamResult(writer));
java.lang.String XMLoutput = writer.getBuffer().toString();
setVariableData("vXMLContent", XMLoutput );
// Set
output
setVariableData( "vJavaErrorCode",
"0" ); // Success
}
catch( Exception e
){
setVariableData( "vJavaErrorCode", "2" ); //
Error
setVariableData( "vJavaErrorMessage", e.getMessage() );
e.printStackTrace();
}
Defining utilization about variables
- vKeyStoreFile – The name of the JKS file;
- vKeyStoreAlias – The alias of the JKS file;
- vKeyStorePassword – The password of the JKS file;
- vXMLContent – This variable will be store all content of XML;
- vJavaErrorCode – This variable will be return 0 for success, 2 for any error;
- vJavaErrorMessage – This variable will return error message when the variable vJavaErrorCode return the value 2.
Related Documents
Defining signature model X509 Base 64 - http://www.w3.org/TR/xmldsig-core/
Incorporating Java and Java EE Code in a BPEL Process - http://docs.oracle.com/cd/E25178_01/dev.1111/e10224/bp_java.htm#BGBEEEFB
Collaborator
Daiane Bitencourt
Collaborator
Daiane Bitencourt