have a problem with Java stored procedure.
Have a cluster with 2 nodes and 1 file system..
In my case, I need to sign XML document (CLOB) with Java stored procedure so I have implemented a Java stored procedure to sign a String and deployed (compiled it) on Oracle 11g.. What I have noticed is that the same procedure works differently if invoked from node A or node B... For example: If I try to sign an XML document on node A the total time to sign the document is about 30 msec. The same code on node B took about 300 msec. I have tried to drop the Java stored procedure and recreate it (compiled) it on node A and the same on node B but the problem remains the same.
DROP JAVA SOURCE "DigitalniPodpis";
CREATE OR REPLACE AND RESOLVE JAVA SOURCE NAMED "DigitalniPodpis" as import java.security.Key;
import java.security.MessageDigest;
import java.security.PrivateKey;
import java.security.Signature;
import java.util.Enumeration;
import java.io.*;
import java.lang.Integer;
import java.security.*;
import java.util.*;
import javax.xml.crypto.dsig.*;
import javax.xml.crypto.dsig.dom.DOMSignContext;
import javax.xml.crypto.dsig.keyinfo.*;
import javax.xml.crypto.dsig.spec.*;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.*;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.*;
import java.net.URL;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
/*********************************************************************************
* Naredil Peter Valencic Izdelava 09.09.2015 Namen metode za generiranje in
* podpisovanje xml datotek za davÄŤno blagajno Datum metoda Spremembe 10.11.2015
* initCert Dodan še trustore, webservice url ter inicializacija HTTPS povezave
*
* //Spodnja verzija je za javo > 1.6.0_25
* //Node node = doc.getElementsByTagName("fu:BusinessPremiseRequest").item(0);
*
* //Spodnja verzija je za javo > 1.6.0_25
* NodeList nl = doc.getElementsByTagName("fu:BusinessPremiseRequest");
* Node node = nl.item(0);
* ((Element) node).setIdAttribute("Id", true);
*
*
* !!!!! PRI PREVAJANJU BODI POZOREN, TRENUNTO JE ZAKOMENTIRAN UKAZ ZA PRIDOBITEV
* NODE-a pri podpisovanju poslovnega prostora in računa!! odkomentiraj ko prevajaš!!
*
**********************************************************************************/
public class DigitalniPodpis {
public static String t="";
public static KeyStore p12 = null;
public static String geslo;
public static String vmesni_rezultat = "";
public static String alias = null;
public static Key privateKey = null;
public static Signature podpis = null;
public static MessageDigest md = null;
public static StringBuilder sb = new StringBuilder();
public static HttpsURLConnection httpsURLConnection; //SSL povezava
public static URL url; //webservice endpoint
public static StringBuffer response = new StringBuffer();
public static String inputLine = "";
//public static DocumentBuilderFactory dbFactory;
static {
try {
podpis = Signature.getInstance("SHA256WithRSA");
md = MessageDigest.getInstance("MD5");
//DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
//dbFactory.setNamespaceAware(true);
} catch (Exception ex) {
}
}
public static HttpsURLConnection getHttpsURLConnection(URL url, String truststore, String keystore,
String keyStorePass, String keyPassword, String KeyStoreType, String KeyManagerAlgorithm, String SSLVersion)
throws NoSuchAlgorithmException, KeyStoreException,
CertificateException, FileNotFoundException, IOException,
UnrecoverableKeyException, KeyManagementException {
//System.setProperty("javax.net.debug", "ssl,handshake,record");
SSLContext sslcontext = SSLContext.getInstance(SSLVersion);
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerAlgorithm);
KeyStore ks = KeyStore.getInstance(KeyStoreType);
ks.load(new FileInputStream(keystore), keyStorePass.toCharArray());
kmf.init(ks, keyPassword.toCharArray());
CertificateFactory cf = CertificateFactory.getInstance("X.509");
InputStream is = new FileInputStream(truststore); //"c:/cert/test-tls.cer");
InputStream caInput = new BufferedInputStream(is);
Certificate ca;
try {
ca = cf.generateCertificate(caInput);
//System.out.println("ca=" + ((X509Certificate) ca).getSubjectDN());
} finally {
caInput.close();
}
String keyStoreType = KeyStore.getDefaultType();
KeyStore keyStore = KeyStore.getInstance(keyStoreType);
keyStore.load(null, null);
keyStore.setCertificateEntry("ca", ca);
// Create a TrustManager that trusts the CAs in our KeyStore
String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
tmf.init(keyStore);
TrustManager[] tm = tmf.getTrustManagers();
sslcontext.init(kmf.getKeyManagers(), tm, null);
SSLSocketFactory sslSocketFactory = sslcontext.getSocketFactory();
HttpsURLConnection.setDefaultSSLSocketFactory(sslSocketFactory);
HttpsURLConnection httpsURLConnection = (HttpsURLConnection) url.openConnection();
return httpsURLConnection;
}
public static String podpisiRacun(String vhodniXml) throws Exception {
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
dbFactory.setNamespaceAware(true);
Document doc = (Document) dbFactory.newDocumentBuilder().parse(new ByteArrayInputStream(vhodniXml.getBytes()));
//Spodnja verzija deluje na java <1.6.0_19x
Node node = doc.getElementsByTagName("fu:InvoiceRequest").item(0);
//Spodnja verzija je za javo > 1.6.0_25
//NodeList nl = doc.getElementsByTagName("fu:InvoiceRequest");
//Node node = nl.item(0);
//(Element)node.setIdAttribute("Id", true);
Enumeration e = p12.aliases();
String alias = (String) e.nextElement();
//System.out.println("Alias certifikata:" + alias);
Key privateKey = p12.getKey(alias, geslo.toCharArray());
KeyStore.PrivateKeyEntry keyEntry
= (KeyStore.PrivateKeyEntry) p12.getEntry(alias, new KeyStore.PasswordProtection(geslo.toCharArray()));
X509Certificate cert = (X509Certificate) keyEntry.getCertificate();
PublicKey publicKey = cert.getPublicKey();
final XMLSignatureFactory sigFactory = XMLSignatureFactory.getInstance("DOM");
// Create a Reference to the enveloped document
Reference ref = sigFactory.newReference("#data",
sigFactory.newDigestMethod(DigestMethod.SHA256, null),
Collections.singletonList(sigFactory.newTransform(Transform.ENVELOPED, (TransformParameterSpec) null)),
null,
null);
SignedInfo si = sigFactory.newSignedInfo(sigFactory.newCanonicalizationMethod(CanonicalizationMethod.INCLUSIVE, (C14NMethodParameterSpec) null), sigFactory.newSignatureMethod("http://www.w3.org/2001/04/xmldsig-more#rsa-sha256", null), Collections.singletonList(ref));
// Create a KeyValue containing the RSA PublicKey
KeyInfoFactory keyInfoFactory = sigFactory.getKeyInfoFactory();
X509IssuerSerial x509IssuerSerial = keyInfoFactory.newX509IssuerSerial(cert.getSubjectX500Principal().getName(), cert.getSerialNumber());
List x509Content = new ArrayList();
x509Content.add(cert.getSubjectX500Principal().getName());
x509Content.add(x509IssuerSerial);
KeyValue keyValue = keyInfoFactory.newKeyValue(publicKey);
X509Data xd = keyInfoFactory.newX509Data(x509Content);
// Create a KeyInfo and add the KeyValue to it
KeyInfo keyInfo = keyInfoFactory.newKeyInfo(Collections.singletonList(xd));
// Create a DOMSignContext and specify the RSA PrivateKey and
// location of the resulting XMLSignature's parent element
DOMSignContext dsc = new DOMSignContext(
privateKey,
node
);
// Create the XMLSignature (but don't sign it yet)
XMLSignature signature = sigFactory.newXMLSignature(si, keyInfo);
// Marshal, generate (and sign) the enveloped signature
signature.sign(dsc);
ByteArrayOutputStream os = new ByteArrayOutputStream();
Transformer trans = TransformerFactory.newInstance()
.newTransformer();
trans.transform(new DOMSource(doc), new StreamResult(os));
byte[] podatki = os.toByteArray();
os.close();
return new String(podatki);
}
public static String podpisiPoslovniProstor(String vhodniXml) throws Exception {
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
dbFactory.setNamespaceAware(true);
Document doc = (Document) dbFactory.newDocumentBuilder().parse(new ByteArrayInputStream(vhodniXml.getBytes()));
//Spodnja verzija je za javo > 1.6.0_25
Node node = doc.getElementsByTagName("fu:BusinessPremiseRequest").item(0);
//Spodnja verzija je za javo > 1.6.0_25
//NodeList nl = doc.getElementsByTagName("fu:BusinessPremiseRequest");
//Node node = nl.item(0);
//((Element) node).setIdAttribute("Id", true);
Enumeration e = p12.aliases();
String alias = (String) e.nextElement();
//System.out.println("Alias certifikata:" + alias);
Key privateKey = p12.getKey(alias, geslo.toCharArray());
KeyStore.PrivateKeyEntry keyEntry
= (KeyStore.PrivateKeyEntry) p12.getEntry(alias, new KeyStore.PasswordProtection(geslo.toCharArray()));
X509Certificate cert = (X509Certificate) keyEntry.getCertificate();
PublicKey publicKey = cert.getPublicKey();
final XMLSignatureFactory sigFactory = XMLSignatureFactory.getInstance("DOM");
// Create a Reference to the enveloped document
Reference ref = sigFactory.newReference("#data",
sigFactory.newDigestMethod(DigestMethod.SHA256, null),
Collections.singletonList(sigFactory.newTransform(Transform.ENVELOPED, (TransformParameterSpec) null)),
null,
null);
SignedInfo si = sigFactory.newSignedInfo(sigFactory.newCanonicalizationMethod(CanonicalizationMethod.INCLUSIVE, (C14NMethodParameterSpec) null), sigFactory.newSignatureMethod("http://www.w3.org/2001/04/xmldsig-more#rsa-sha256", null), Collections.singletonList(ref));
// Create a KeyValue containing the RSA PublicKey
KeyInfoFactory keyInfoFactory = sigFactory.getKeyInfoFactory();
X509IssuerSerial x509IssuerSerial = keyInfoFactory.newX509IssuerSerial(cert.getSubjectX500Principal().getName(), cert.getSerialNumber());
List x509Content = new ArrayList();
x509Content.add(cert.getSubjectX500Principal().getName());
x509Content.add(x509IssuerSerial);
KeyValue keyValue = keyInfoFactory.newKeyValue(publicKey);
X509Data xd = keyInfoFactory.newX509Data(x509Content);
// Create a KeyInfo and add the KeyValue to it
KeyInfo keyInfo = keyInfoFactory.newKeyInfo(Collections.singletonList(xd));
// Create a DOMSignContext and specify the RSA PrivateKey and
// location of the resulting XMLSignature's parent element
DOMSignContext dsc = new DOMSignContext(
privateKey,
node
);
// Create the XMLSignature (but don't sign it yet)
XMLSignature signature = sigFactory.newXMLSignature(si, keyInfo);
// Marshal, generate (and sign) the enveloped signature
signature.sign(dsc);
ByteArrayOutputStream os = new ByteArrayOutputStream();
Transformer trans = TransformerFactory.newInstance()
.newTransformer();
trans.transform(new DOMSource(doc), new StreamResult(os));
return new String(os.toByteArray());
}
private static String md5Java(byte[] message) throws Exception {
byte[] hash = md.digest(message); //.getBytes("UTF-8"));
//StringBuilder sb = new StringBuilder(2 * hash.length);
sb.setLength(0);
for (byte b : hash) {
sb.append(String.format("%02x", b & 0xff));
}
return sb.toString();
}
/**
* Metoda inicializira keystore in truststore za SSL povezavo ter podpis
* dokumentov
*
* @param direktorij direktorij kjer se fiziÄŤno nahajajo certifikati
* @param certifikat naziv datoteke certifikata
* @param gesloc Geslo certifikata
* @param trustStoreCertifikat naziv trustStore certifikata
* @throws Exception
*/
public static void initCert(String direktorij, String certifikat, String gesloc, String trustStoreCertifikat, String urlWsEndpoint) throws Exception {
if (certifikat == null) {
throw new Exception("ime datoteke certifikata za podpis podatkov ni podano!");
}
if (gesloc == null) {
throw new Exception("geslo certifikata ni podano!");
}
if (trustStoreCertifikat == null) {
throw new Exception("ime datoteke certifikata za trustStore ni podano!");
}
File f = new File(direktorij+"/"+certifikat);
if (f.exists() == false)
{
throw new Exception("Certifikat za podpis ne obstaja na:" + (direktorij+"/"+certifikat));
}
f = new File(direktorij+"/"+trustStoreCertifikat);
if (f.exists() == false)
{
throw new Exception("Certifikat za dostop do https ne obstaja na:" + (direktorij+"/"+trustStoreCertifikat));
}
// doloÄŤimo URL do webservisa
url = new URL(urlWsEndpoint);
geslo = gesloc;
if (p12 == null) {
p12 = KeyStore.getInstance("pkcs12");
p12.load(new FileInputStream(direktorij + "/" + certifikat), geslo.toCharArray());
Enumeration e = p12.aliases();
alias = (String) e.nextElement();
privateKey = p12.getKey(alias, geslo.toCharArray());
podpis.initSign((PrivateKey) privateKey);
}
//parametri za SSL povezavo
if (httpsURLConnection == null) {
SSLContext sslcontext = SSLContext.getInstance("TLSv1.2");
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
KeyStore ks = KeyStore.getInstance("PKCS12");
ks.load(new FileInputStream(direktorij + "/" + certifikat), geslo.toCharArray());
kmf.init(ks, geslo.toCharArray());
CertificateFactory cf = CertificateFactory.getInstance("X.509");
InputStream is = new FileInputStream(direktorij + "/" + trustStoreCertifikat); //"c:/cert/test-tls.cer");
InputStream caInput = new BufferedInputStream(is);
Certificate ca;
try {
ca = cf.generateCertificate(caInput);
//System.out.println("ca=" + ((X509Certificate) ca).getSubjectDN());
} finally {
caInput.close();
}
String keyStoreType = KeyStore.getDefaultType();
KeyStore keyStore = KeyStore.getInstance(keyStoreType);
keyStore.load(null, null);
keyStore.setCertificateEntry("ca", ca);
// Create a TrustManager that trusts the CAs in our KeyStore
String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
tmf.init(keyStore);
TrustManager[] tm = tmf.getTrustManagers();
sslcontext.init(kmf.getKeyManagers(), tm, null);
SSLSocketFactory sslSocketFactory = sslcontext.getSocketFactory();
HttpsURLConnection.setDefaultSSLSocketFactory(sslSocketFactory);
//vrnemo https povezavo, ki je globalna in aktivna skozi celo sejo.
//httpsURLConnection = (HttpsURLConnection) url.openConnection();
}
}
public static String sendXML(String soapAction,String soapEnvelopeXML) throws Exception {
//nastavimo timeout
//httpsURLConnection.setConnectTimeout(Integer.valueOf(timeoutMsec).intValue());
if (httpsURLConnection == null) {
httpsURLConnection = (HttpsURLConnection) url.openConnection();
}
//nastavimo header-je
httpsURLConnection.setRequestMethod("POST");
httpsURLConnection.setRequestProperty("User-Agent", "Mozilla/5.0");
httpsURLConnection.setRequestProperty("Accept-Language", "en-US,en;q=0.5");
httpsURLConnection.setRequestProperty("Content-type", "text/xml; charset=utf-8");
httpsURLConnection.setRequestProperty("SOAPAction", soapAction);
httpsURLConnection.setDoOutput(true);
OutputStream reqStream = httpsURLConnection.getOutputStream();
reqStream.write(soapEnvelopeXML.getBytes());
int responseCode = httpsURLConnection.getResponseCode();
//System.out.println("\nSending 'POST' request to URL : " + url);
//System.out.println("Response Code : " + responseCode);
if (responseCode == 200) {
BufferedReader in = new BufferedReader(
new InputStreamReader(httpsURLConnection.getInputStream()));
String inputLine;
// StringBuffer response = new StringBuffer();
response.setLength(0);
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
httpsURLConnection.disconnect();
return response.toString();
}
else
{
httpsURLConnection.disconnect();
throw new Exception("Napaka pri povezavi na streĹľnik "+ url + ". Koda napake: " + responseCode);
}
}
public static String sendXMLT(int timeout,String soapAction,String soapEnvelopeXML) throws Exception {
httpsURLConnection = (HttpsURLConnection) url.openConnection();
//nastavimo timeout
httpsURLConnection.setConnectTimeout(timeout);
httpsURLConnection.setReadTimeout(timeout);
//nastavimo header-je
httpsURLConnection.setRequestMethod("POST");
httpsURLConnection.setRequestProperty("User-Agent", "Mozilla/5.0");
httpsURLConnection.setRequestProperty("Accept-Language", "en-US,en;q=0.5");
httpsURLConnection.setRequestProperty("Content-type", "text/xml; charset=utf-8");
httpsURLConnection.setRequestProperty("SOAPAction", soapAction);
httpsURLConnection.setDoOutput(true);
OutputStream reqStream = httpsURLConnection.getOutputStream();
reqStream.write(soapEnvelopeXML.getBytes());
int responseCode = httpsURLConnection.getResponseCode();
//System.out.println("\nSending 'POST' request to URL : " + url);
//System.out.println("Response Code : " + responseCode);
if (responseCode == 200) {
BufferedReader in = new BufferedReader(
new InputStreamReader(httpsURLConnection.getInputStream()));
response.setLength(0);
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
httpsURLConnection.disconnect();
return response.toString();
}
else
{
httpsURLConnection.disconnect();
throw new Exception("Napaka pri povezavi na streĹľnik "+ url + ". Koda napake: " + responseCode);
}
}
public static String getZOI(
String davcnaStevilka,
String datumIzdaje,
String stevilkaRacuna,
String oznakaPoslovnegaProstora,
String electronicDeviceId,
String znesekRacuna) throws Exception {
//sestavimo vrstico
vmesni_rezultat = davcnaStevilka.concat(datumIzdaje).concat(stevilkaRacuna).concat(oznakaPoslovnegaProstora).concat(electronicDeviceId).concat(znesekRacuna);
podpis.update(vmesni_rezultat.getBytes("UTF-8"));
byte[] podpisano = podpis.sign();
//MD5 hash
return md5Java(podpisano);
}
}
/
Is something that I'm missing? Why the same code works differently if invoked on node A or B?
Do you think If I try to "load" only the class file with loadjava will resolve this problem?