Exception while include .p12 file in java - java

I have .p12 certificate file which needs to be included in every sent to server from my java code.
When i run sample code from linux its gives me exception
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path validation failed: java.security.cert.CertPathValidatorException: timestamp check failed
My java code is below :
HttpsURLConnection con = null;
try
{
System.out.println("Calling webservice ..... ");
char[] passw = "mypassword".toCharArray();
KeyStore ks = KeyStore.getInstance("PKCS12");
InputStream keyInput = new FileInputStream( "/usr/local/KEYSTORE.p12");
ks.load(keyInput, passw );
keyInput.close();
System.out.println("Reading certificate file Completed");
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(ks, passw);
System.out.println("Set SSL certificate");
SSLContext sclx = SSLContext.getInstance("SSL");
sclx.init( kmf.getKeyManagers(), null, new SecureRandom());
SSLContext.setDefault(sclx);
HttpsURLConnection.setDefaultSSLSocketFactory(sclx.getSocketFactory());
URL url = new URL("https://myurl.server.com");
con = (HttpsURLConnection)url.openConnection();
System.out.println("Connection successfull");
//con.setSSLSocketFactory(sclx.getSocketFactory());
System.out.println("Token Id 026F800E-562D-4B0F-BC56-AC16895072F4");
if(con!=null)
{
System.out.println("Inside connection");
con.setRequestProperty("Content-Type","application/json;charset=utf-8");
con.setRequestProperty("Accept", "application/json");
con.setRequestProperty("Accept-Charset", "UTF-8");
con.setRequestProperty("Token-Id","026F800E-562D-4B0F-BC56-AC16895072F4");
con.setDoOutput(true);
con.setDoInput(true);
con.setUseCaches(false);
con.setDefaultUseCaches(false);
con.setRequestMethod("POST");
con.connect();
OutputStreamWriter os = new OutputStreamWriter(con.getOutputStream(), "UTF-8");
os.write("request String");
os.flush();
os.close();
InputStreamReader dis = new InputStreamReader(con.getInputStream(),"UTF-8");
if (null != dis)
{
System.out.println("Reading response from webservice 1");
BufferedReader reader = new BufferedReader(dis);
String line;
while((line = reader.readLine()) != null) {
System.out.println(line);
}
}
}
}
catch(IOException ioex)
{
System.err.println("Exception : "+ioex);
e.printStackTrace();
}
catch(Exception ex){
ex.printStackTrace();
}
finally{
if(con != null) {
con.disconnect();
}
}
Its work on windows server but gives exception on linux server.
Please any one help me to resolved this.

Related

Getting Method threw 'javax.net.ssl.SSLException' exception

I'm trying to hit api1 which gives me a token for authentication for api2. However i'm getting this error from Connection.getOutputStream() Method threw 'javax.net.ssl.SSLException' exception.
Any idea how to fix this?
public HttpsURLConnection getHttpsURLConnection(HttpParameterSetter parameters, URL url, String method) throws IOException {
HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
connection.setRequestMethod(method);
parameters.getHeaders().forEach(connection::setRequestProperty);
return connection;
}
public String requests(URL url) throws Exception {
url = new URL(url.toString() + "?" + parameters.toString());
HttpsURLConnection connection = getHttpsURLConnection(this.parameters, url, this.method);
connection.setDoOutput(true);
BufferedReader in = null;
DataOutputStream wr = null;
try {
if (!payload.equals("")) {
wr = new DataOutputStream(connection.getOutputStream());
wr.writeBytes(this.getPayload());
wr.flush();
wr.close();
}
in = new BufferedReader(new InputStreamReader(connection.getInputStream(), StandardCharsets.UTF_8));
StringBuilder inputLine = new StringBuilder();
String line;
while ((line = in.readLine()) != null)
inputLine.append(line);
return inputLine.toString();
} catch (Exception e) {
log.error("Exception occurred during token call "+e.getMessage());
throw e;
} finally {
try{
if (wr != null)
wr.close();
}catch (Exception e){
log.error("Error occurred while closing DataOutputStream in the token call: "+e.getMessage());
}
try{
if (in != null)
in.close();
}catch (Exception e){
log.error("Error occurred while closing BufferedReader in the token call: "+e.getMessage());
}
}
}**strong text**
Does the server you are trying to connect to use a self-signed certificate?
If so, please make sure you have imported the self-signed certificate into your jre KeyStore.
Here is an example:
keytool -keystore "%JAVA_HOME%\jre\lib\security\cacerts" -importcert -alias <alias> -file <certificate> -trustcacerts -keypass changeit -storepass changeit
<certificate> is the filename of the certificate, such as xxx.cer or xxx.crt.

Internal File SSL Cert with Password fails

I'm in a Spring boot service, that will be within a microservice, attempting to connect to an external SOAP Web Service, that requires a cert that was created by that service and a password. This is being written in Windows, but will need to be run on Unix. Right now, I've hardcoded some things for Windows. This is what I have coded for my side, but I'm getting an error on httpConn.getInputStream():
"sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target".
Can someone help me understand what I'm missing?
public String getSoapData(String contentType) throws IOException, NoSuchAlgorithmException, KeyManagementException, CertificateException, KeyStoreException {
StringBuilder retVal = new StringBuilder();
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
// get user password and file input stream
char[] password = "MYPass".toCharArray();
java.io.FileInputStream fis = null;
//X509Certificate caCert = null;
//CertificateFactory cf = CertificateFactory.getInstance("X.509");
try {
fis = new java.io.FileInputStream("C:\\MyCerts\\dev_HubExplorer1.pfx");
ks.load(fis, password);
//caCert = (X509Certificate)cf.generateCertificate(fis);
//ks.setCertificateEntry("caCert", caCert);
} catch (Exception e) {
Common.screenPrint("Exception while importing certificate:%s%s", Common.CRLF, e.getMessage());
} finally {
if (fis != null) {
fis.close();
}
}
tmf.init(ks);
//TODO (GWL) Need to get this from a configuration file/db.
SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
sslContext.init(null, tmf.getTrustManagers(), new java.security.SecureRandom());
URL url = new URL(_publicRecordURL);
HttpsURLConnection httpConn = (HttpsURLConnection) url.openConnection();
httpConn.setSSLSocketFactory(sslContext.getSocketFactory());
byte[] bytes = _requestTemplate.getBytes();
// Set the appropriate HTTP parameters.
httpConn.setRequestProperty("Content-Length", String.valueOf( bytes.length ) );
httpConn.setRequestProperty("Content-Type","text/xml; charset=utf-8");
httpConn.setRequestProperty("SOAPAction",_soapAction);
httpConn.setRequestProperty("Accept","text/xml");
httpConn.setRequestMethod( "POST" );
httpConn.setDoOutput(true);
httpConn.setDoInput(true);
//Everything's set up; send the XML that was read in to b.
OutputStreamWriter writer = new OutputStreamWriter(httpConn.getOutputStream());
writer.write(_requestTemplate);
writer.flush();
//Read the response and write it to standard out.
InputStreamReader isr = new InputStreamReader(httpConn.getInputStream());
BufferedReader in = new BufferedReader(isr);
String inputLine;
while ((inputLine = in.readLine()) != null) {
retVal.append(inputLine + Common.CRLF);
System.out.println(inputLine);
}
in.close();
return retVal.toString();
}
you can follow this stackoverflow answer to get the solution of this problem :
https://stackoverflow.com/a/12146838/7801800

Java webapp with two URL connections: basic auth and cert auth

I have a java webapp which uses this class for connecting to server by using basic auth and cert. It works fine separately (without creating other url connections):
public void connectCert(String jsonParams) {
try {
KeyStore clientStore = KeyStore.getInstance("PKCS12");
clientStore.load(new FileInputStream("d:\\certs\\api\\xx.p12"), "W*53as_G".toCharArray());
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(clientStore, "W*53as_G".toCharArray());
KeyManager[] kms = kmf.getKeyManagers();
KeyStore trustStore = KeyStore.getInstance("JKS");
trustStore.load(new FileInputStream("c:\\jdk1.8.0_51\\jre\\lib\\security\\cacerts"), "changeit".toCharArray());
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(trustStore);
TrustManager[] tms = tmf.getTrustManagers();
SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(kms, tms, new SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
URL url = new URL("https://apis2s.ee/test");
HttpsURLConnection urlConn = (HttpsURLConnection) url.openConnection();
urlConn.setRequestProperty("Authorization", "Basic " + Base64.encode("andrey:pass_1".getBytes()));
urlConn.setUseCaches(false);
urlConn.setAllowUserInteraction(true);
urlConn.setRequestProperty("Pragma", "no-cache");
urlConn.setRequestProperty("Content-type", "application/x-www-form-urlencoded");
urlConn.setRequestProperty("Content-length", Integer.toString(jsonParams.length()));
urlConn.setDoOutput(true);
urlConn.setRequestProperty("Content-Length", Integer.toString(jsonParams.length()));
PrintStream out = new PrintStream(urlConn.getOutputStream());
out.print(jsonParams);
out.flush();
out.close();
StringBuilder builder = new StringBuilder();
int responseCode = urlConn.getResponseCode();
builder.append(responseCode).append(" ").append(urlConn.getResponseMessage()).append("\n");
InputStream inputStream = null;
if (responseCode == 200) inputStream = urlConn.getInputStream();
else inputStream = urlConn.getErrorStream();//this returns 400
Scanner in = new Scanner(inputStream);
String responseStr = "";
while (in.hasNextLine()) {
String str = in.nextLine();
responseStr += str;
}
System.out.println(builder);
System.out.println("responseStr: " + responseStr);
} catch (Exception e) {
}
}
Also I need to create in my webapp a connection to another server by using basic auth (without certificate):
private InputStream connectHTTPS(String loginData, String url, String params) {
TrustManager[] trustAllCerts =
new TrustManager[]{
new X509TrustManager(){
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType){
}
public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType) {
}
public boolean isClientTrusted(java.security.cert.X509Certificate[] certs) {
return true;
}
public boolean isServerTrusted(java.security.cert.X509Certificate[] certs) {
return true;
}
}};
HostnameVerifier verifier = new HostnameVerifier() {
public boolean verify(String string, SSLSession sSLSession) {
return true;
}
public boolean verify(String string, String string2) {
return true;
}
};
SSLContext sc = null;
try{
sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
javax.net.ssl.HttpsURLConnection.setDefaultHostnameVerifier(verifier);
}catch(Exception e){
e.printStackTrace();
}
javax.net.ssl.HttpsURLConnection.setDefaultHostnameVerifier(verifier);
URL serverURL = null;
try{
serverURL = new URL(null,url,new sun.net.www.protocol.https.Handler());
}catch (Exception e){
e.printStackTrace();
}
javax.net.ssl.HttpsURLConnection urlConn = null;
try{
urlConn = (javax.net.ssl.HttpsURLConnection)serverURL.openConnection();
urlConn.setSSLSocketFactory(sc.getSocketFactory());
urlConn.setRequestMethod("POST");
}catch(Exception i){
i.printStackTrace();
}
InputStream res = null;
urlConn.setDoOutput(true);
if(useLogin)
urlConn.setRequestProperty("Authorization", "Basic " + loginData);
urlConn.setUseCaches(false);
urlConn.setAllowUserInteraction(true);
urlConn.setRequestProperty("Pragma", "no-cache");
urlConn.setRequestProperty("Content-type", "application/x-www-form-urlencoded");
urlConn.setRequestProperty("Content-length", Integer.toString(params.length()));
try{
PrintStream out = new PrintStream(urlConn.getOutputStream());
out.print(params);
out.flush();
out.close();
res = urlConn.getInputStream();
}catch(Exception o){
o.printStackTrace();
}
return res;
}
If connectHTTPS() is invoked before connectCert() then I get
<html><head><title>400 No required SSL certificate was sent</title></head><body
bgcolor="white"><center><h1>400 Bad Request</h1></center><center>No required SSL certificate was sent</center><hr><center>nginx</center></body></html>
How can I solve the cert issue with the both connections in one webapp?
The issue was resolved by modifying the connectHTTPS() and removing all ssl factory/context configuration. The connectCert() was not changed. The updated method looks like below
private InputStream connectHTTPS(boolean useLogin, boolean showServerError, String loginData, String url, String params) {
InputStream res = null;
HttpURLConnection connect =null;
try{
URL theURL = new URL(url);
connect = (HttpURLConnection)theURL.openConnection();
connect.setRequestMethod("POST");
connect.setUseCaches(false);
connect.setDoOutput(true);
if(useLogin)
connect.setRequestProperty("Authorization", "Basic " + loginData);
connect.setRequestProperty("Pragma", "no-cache");
connect.setRequestProperty("Content-type", "application/x-www-form-urlencoded");
connect.setRequestProperty("Content-length", Integer.toString(params.length()));
PrintStream out = new PrintStream(connect.getOutputStream());
out.print(params);
out.flush();
out.close();
res = connect.getInputStream();
}catch(IOException iox){
if (showServerError && connect != null){
res = connect.getErrorStream();
} else {
res = new ByteArrayInputStream((iox.getMessage()).getBytes());
}
}
return res;
}
Thank you pedrofb for the suggestions.

Android/Eclipse Open a file Outside the MainActivity in a Plugin

I have a problem with my Android Phonegap App.
I created a plugin to send Data from HTML/JAVASCRIPT to Java and Java will send this DATA to a
Server with HTTPS post.
To get this Worke I need to Open a ssl.crt (certification) from my Asset folder.
In the Cordova Class this function dose work because it extends the CordovaActivity.
My Plugin Class : public class ConnectPlugin extends CordovaPlugin
Here is the Login method:
protected String tryLogin_2(String d1) throws CertificateException, FileNotFoundException, IOException, KeyStoreException, NoSuchAlgorithmException, KeyManagementException
{
// Load CAs from an InputStream
// (could be from a resource or ByteArrayInputStream or ...)
CertificateFactory cf = CertificateFactory.getInstance("X.509");
// From https://www.washington.edu/itconnect/security/ca/load-der.crt
InputStream caInput = new BufferedInputStream(this.getAssets().open("ssl.crt"));
java.security.cert.Certificate ca;
try {
ca = cf.generateCertificate(caInput);
} finally {
caInput.close();
}
// Create a KeyStore containing our trusted CAs
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);
// Create an SSLContext that uses our TrustManager
SSLContext context = SSLContext.getInstance("TLS");
context.init(null, tmf.getTrustManagers(), null);
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
String httpsURL = "https://URL.com";
OutputStreamWriter request = null;
DataInputStream response_2 = null;
String parameters = "1="+d1;
String response = null;
try
{
URL myurl = new URL(httpsURL);
HttpsURLConnection con = (HttpsURLConnection)myurl.openConnection();
con.setSSLSocketFactory(context.getSocketFactory());
con.setRequestMethod("POST");
con.setRequestProperty("Content-length", String.valueOf(query.length()));
con.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
con.setDoOutput(true);
con.setDoInput(true);
request = new OutputStreamWriter(con.getOutputStream());
request.write(parameters);
request.flush();
request.close();
String line = "";
InputStreamReader isr = new InputStreamReader(con.getInputStream());
BufferedReader reader = new BufferedReader(isr);
StringBuilder sb = new StringBuilder();
while ((line = reader.readLine()) != null)
{
sb.append(line + "\n");
}
//Response from server after login process will be stored in response variable.
response = sb.toString();
isr.close();
reader.close();
}
catch(IOException e)
{
response = "Error"; // Error
}
return response;
}
The problem now is "The method getAssets() is undefined for the type ConnectPlugin".
I can't use the getAssets() method outside the Main Class.
In my MainClass the obove code work 100% fine and sends a request to my server.
But not in my Plugin Class.
Use
cordova.getActivity().getAssets().open("ssl.crt"));

Android HttpsUrlConnection with POST data not work on Gingerbread

I've written code to download some data from external server. The server is using self-signed certificate, need to have session cookie set and some POST data. Currently I have the following code:
private byte[] getResponse(URL url, String postData)
throws IOException, KeyManagementException, CertificateException, KeyStoreException,
NoSuchAlgorithmException
{
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection();
urlConnection.setRequestProperty("User-Agent", userAgent);
urlConnection.setRequestProperty("Cookie", cookie);
urlConnection.setRequestMethod("POST");
urlConnection.setDoInput(true);
urlConnection.setDoOutput(true);
urlConnection.setSSLSocketFactory(getSocketFactory());
OutputStream os = urlConnection.getOutputStream();
BufferedWriter writer = new BufferedWriter(
new OutputStreamWriter(os, "UTF-8"));
writer.write(postData);
writer.flush();
writer.close();
os.close();
try {
urlConnection.connect();
InputStream is = urlConnection.getInputStream();
int len = 0;
while ((len = is.read(buffer)) != -1)
{
baos.write(buffer, 0, len);
}
}
catch(IOException e)
{
throw e;
}
finally {
urlConnection.disconnect();
}
return baos.toByteArray();
}
On Ice Cream Sandwich and higher (API >= 14) everything works fine. The problem started when I tried to make the app work on API >= 8. It is now properly sending the request with GET and no params (CAPTCHA) but when it comes to getting the actual data urlConnection's connect method fails with no exception. The code for getSocketFactory() is:
private SSLSocketFactory getSocketFactory()
throws CertificateException, IOException, KeyStoreException, NoSuchAlgorithmException,
KeyManagementException
{
CertificateFactory cf = CertificateFactory.getInstance("X.509");
InputStream caInput = context.getResources().openRawResource(R.raw.historiapojazdu);
Certificate ca;
try {
ca = cf.generateCertificate(caInput);
} finally {
caInput.close();
}
// Create a KeyStore containing our trusted CAs
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);
// Create an SSLContext that uses our TrustManager
SSLContext context = SSLContext.getInstance("TLS");
context.init(null, tmf.getTrustManagers(), null);
return context.getSocketFactory();
}
EDIT: I've just realized that connect method apparently worked but it didn't follow redirect on the response so input stream was always empty.
I've just figured it myself. It looks like HttpsUrlConnection simply does not follow redirects on API 10 and lower for some reason even despite implicitly calling setInstanceFollowRedirects(true). It is just ignoring that setting. I've worked that around with this code just after calling urlConnection.connect():
String redirect = urlConnection.getHeaderField("Location");
if(redirect != null) //truth before ICS
{
urlConnection.disconnect();
urlConnection = (HttpsURLConnection) (new URL(redirect)).openConnection();
urlConnection.setRequestProperty("User-Agent", userAgent);
urlConnection.setRequestProperty("Cookie", cookie);
urlConnection.setRequestMethod("POST");
urlConnection.setDoInput(true);
urlConnection.setDoOutput(true);
urlConnection.setSSLSocketFactory(getSocketFactory());
OutputStream os2 = urlConnection.getOutputStream();
BufferedWriter writer2 = new BufferedWriter(
new OutputStreamWriter(os2, "UTF-8"));
writer2.write(postData);
writer2.flush();
writer2.close();
os2.close();
urlConnection.connect();
}

Categories

Resources