I reciverd a .p12 certificate, that I need to use a web service. If I import the certificate in my browser, I can access the service, but if I try to perform a POST request, I get this error:
Caused by: java.security.cert.CertPathValidatorException: critical policy qualifiers present in certificate
at sun.security.provider.certpath.PKIXMasterCertPathValidator.validate(PKIXMasterCertPathValidator.java:139)
at sun.security.provider.certpath.PKIXCertPathValidator.doValidate(PKIXCertPathValidator.java:328)
at sun.security.provider.certpath.PKIXCertPathValidator.engineValidate(PKIXCertPathValidator.java:178)
at java.security.cert.CertPathValidator.validate(CertPathValidator.java:250)
at sun.security.validator.PKIXValidator.doValidate(PKIXValidator.java:275)
... 24 more
Here is my code:
KeyStore clientStore = KeyStore.getInstance("PKCS12");
clientStore.load(new FileInputStream("client.p12"), "password".toCharArray());
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(clientStore, "password".toCharArray());
KeyManager[] kms = kmf.getKeyManagers();
KeyStore trustStore = KeyStore.getInstance("JKS");
trustStore.load(new FileInputStream("client.keystore"), "password".toCharArray());
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(trustStore);
TrustManager[] tms = tmf.getTrustManagers();
SSLContext sslContext = null;
sslContext = SSLContext.getInstance("TLS");
sslContext.init(kms, tms, new SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
URL url = new URL("https://cistest.apis-it.hr:8446/g2bservis");
HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
String query = "<SendDocument></SendDocument>";
con.setRequestMethod("POST");
con.setRequestProperty("Content-Type","text");
con.setDoOutput(true);
con.setDoInput(true);
DataOutputStream output = new DataOutputStream(con.getOutputStream());
output.writeBytes(query);
output.close();
DataInputStream input = new DataInputStream( con.getInputStream() );
for( int c = input.read(); c != -1; c = input.read() )
System.out.print( (char)c );
input.close();
System.out.println("Resp Code:"+con .getResponseCode());
System.out.println("Resp Message:"+ con .getResponseMessage());
The excetion happens on con.getOutputStream()
I resolved the problem by exporting the server's certificate from chrome and using that instead of the default root certificate I had for the page. I noticed that certificate might be the problem, when I was able to open the page in chrome but not in firefox.
Related
I need a post request to the server where I will authorize with a certificate. I have the certificate in file.p12 secured by a password. I think I have checked all the solutions on this site and unfortunately none of them work.
I wanted to use OkHttp, but all solutions use libraries that have already been removed.
KeyStore ks = KeyStore.getInstance("PKCS12");
FileInputStream fis = new FileInputStream("C://tls.p12");
ks.load(fis, "password".toCharArray());
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
kmf.init(ks, "password".toCharArray());
SSLContext sc = SSLContext.getInstance("TLS");
sc.init(kmf.getKeyManagers(), null, null);
URL url = new URL("https://.....");
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init((KeyStore) null);
TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
if (trustManagers.length != 1 || !(trustManagers[0] instanceof X509TrustManager)) {
throw new IllegalStateException("Unexpected default trust managers:" + Arrays.toString(trustManagers));
}
X509TrustManager trustManager = (X509TrustManager) trustManagers[0];
SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, new TrustManager[] { trustManager }, null);
OkHttpClient client = new OkHttpClient.Builder()
.sslSocketFactory(sc.getSocketFactory(), trustManager)
.build();
I've this code in java 8
String u = "https://test.com.asmx?WSDL";
String pwd = "aaaa";
String pathP12 = "1234.p12";
KeyStore ks = KeyStore.getInstance("PKCS12");
FileInputStream fis = new FileInputStream(pathP12);
ks.load(fis, pwd.toCharArray());
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
kmf.init(ks, pwd.toCharArray());
URL url = new URL(u);
SSLContext sc = SSLContext.getInstance("TLSv1");
sc.init(kmf.getKeyManagers(), null, new java.security.SecureRandom());
HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
con.setSSLSocketFactory(sc.getSocketFactory());
System.out.println("After url connection");
How can i set TLSv1 and keystore in a SoapActionCallback in Spring Boot
ProvaResponse response = (ProvaResponse) getWebServiceTemplate().marshalSendAndReceive(
request,
new SoapActionCallback("http://www.test.com/Prova")
);
I have an android app that needs to connect to a server using REST. I use Retrofit 2 for the requests and it works well.
The problem is when I want to use an SSL connection. With open ssl, i have a client.crt, myPrivateKey.pem and request.csr. I also have a rootCA that I used to encrypt the client and the server certificate.
When I check online, I find a lot of solutions with one CA files.
This is the code I have so far.
// https://developer.android.com/training/articles/security-ssl.html#java
private OkHttpClient initClient(boolean ssl) {
if (ssl) {
SSLSocketFactory sslSocketFactory = null;
X509TrustManager x509TrustManager = null;
try {
CertificateFactory cf = CertificateFactory.getInstance("X.509");
InputStream certificateFileCRT = mContext.getResources().openRawResource(R.raw.client);
Certificate certCRT = cf.generateCertificate(certificateFileCRT);
System.out.println("ca=" + ((X509Certificate) certCRT).getSubjectDN());
certificateFileCRT.close();
String keyStoreType = KeyStore.getDefaultType();
KeyStore keyStore = KeyStore.getInstance(keyStoreType);
keyStore.load(null, null);
keyStore.setCertificateEntry("ca", certCRT);
String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
tmf.init(keyStore);
TrustManager[] trustManagers = tmf.getTrustManagers();
x509TrustManager = (X509TrustManager) trustManagers[0];
SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, new TrustManager[]{x509TrustManager}, null);
sslSocketFactory = sslContext.getSocketFactory();
} catch (CertificateException |IOException | KeyStoreException | NoSuchAlgorithmException | KeyManagementException e) {
e.printStackTrace();
}
return new OkHttpClient.Builder()
.readTimeout(60, TimeUnit.SECONDS)
.sslSocketFactory(sslSocketFactory, x509TrustManager)
.build();
// return getUnsafeOkHttpClient();
} else {
return new OkHttpClient.Builder()
.readTimeout(60, TimeUnit.SECONDS)
.build();
}
}
When I send a request to the client I get java.security.cert.CertPathValidatorException trust anchor for certification path not found.
Can you please help me creating my client with my certificate and my key!
I fixed my code base from this website
private OkHttpClient initClient() throws KeyStoreException, CertificateException, NoSuchAlgorithmException, IOException, UnrecoverableKeyException, KeyManagementException {
// Trust self signed certificate
InputStream certificateFileCRT = mContext.getResources().openRawResource(R.raw.server);
CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
X509Certificate cert = (X509Certificate) certificateFactory.generateCertificate(certificateFileCRT);
String alias = cert.getSubjectX500Principal().getName();
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
trustStore.load(null);
trustStore.setCertificateEntry(alias, cert);
// KeyStore containing client certificate
KeyStore keyStore = KeyStore.getInstance("PKCS12");
InputStream fis = mContext.getResources().openRawResource(R.raw.client);
keyStore.load(fis, "PASSWORD".toCharArray());
// Build an SSL context
KeyManagerFactory kmf = KeyManagerFactory.getInstance("X509");
kmf.init(keyStore, "PASSWORD".toCharArray());
KeyManager[] keyManagers = kmf.getKeyManagers();
TrustManagerFactory tmf = TrustManagerFactory.getInstance("X509");
tmf.init(trustStore);
TrustManager[] trustManagers = tmf.getTrustManagers();
SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(keyManagers, trustManagers, null);
return new OkHttpClient.Builder()
.readTimeout(60, TimeUnit.SECONDS)
.sslSocketFactory(sslContext.getSocketFactory())
.hostnameVerifier(new HostnameVerifier() {
#Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
})
.build();
}
Here, I am creating client project and trying to call/consume soap webservice.
But every time getting same error
HTTP transport error: java.net.ConnectException: Connection timed out: connect
It is very secured and vendor provided certificate and password to consume it.
I am little bit confused with the SSL configuration. Please check following code and suggest right way to do all SSL configuration if its wrong.
systemProps.setProperty("javax.net.ssl.keyStore", new File("Path of Certificate").getAbsolutePath());
systemProps.setProperty("javax.net.ssl.keyStorePassword", "***");
systemProps.setProperty("javax.net.ssl.keyStoreType", "pkcs12");
systemProps.setProperty("java.net.useSystemProxies", "true");
String provider = System.getProperty("javax.net.ssl.keyStoreProvider");
String keyStoreType = systemProps.getProperty("javax.net.ssl.keyStoreType");
KeyStore ks = null;
if (provider != null) {
ks = KeyStore.getInstance(keyStoreType, provider);
} else {
ks = KeyStore.getInstance(keyStoreType);
}
InputStream ksis = null;
String keystorePath = systemProps.getProperty("javax.net.ssl.keyStore");
String keystorePassword = systemProps.getProperty("javax.net.ssl.keyStorePassword");
if (keystorePath != null && !"NONE".equals(keystorePath)) {
ksis = new FileInputStream(keystorePath);
}
try {
ks.load(ksis, keystorePassword.toCharArray());
} finally {
if (ksis != null) { ksis.close(); }
}
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(ks, keystorePassword.toCharArray());
// Note that there is no property for the key password itself, which may be different.
// We're using the keystore password too.
SSLContext sc = SSLContext.getInstance("SSLv3");
sc.init(kmf.getKeyManagers(), null, null);
((BindingProvider) ps).getRequestContext().put("com.sun.xml.internal.ws.transport.https.client.SSLSocketFactory", sc.getSocketFactory());
Response response = ps.submitRequest(request); service call.
System.out.println(response.toString());
Here, I have not provided webservice URL anywhere and i dont know where to provide that in above code. Any suggestion if this might be the issue.
I'm trying to download a zip file from an url but the url returns a 404 page with the app.
When I try with firefox, it just asked the keystore so I put it and it works : I can download the ZIP file.
I don't really understand what I'm doing wrong.
Here is my code
URL url = new URL(reportInfo.getURI().toString());
HttpsURLConnection con = (HttpsURLConnection) url
.openConnection();
/*
* Keystore manager
*/
KeyManagerFactory keyManagerFactory = KeyManagerFactory
.getInstance("SunX509");
String pKeyPassword = GSBConstants.KEYSTORE_PASSWORD;
KeyStore keyStore = KeyStore.getInstance("JKS");
InputStream keyInput = new FileInputStream(new File(
cc.getWorkingDir() + File.separator
+ GSBConstants.KEYSTOREJKS_NAME));
keyStore.load(keyInput, pKeyPassword.toCharArray());
keyInput.close();
keyManagerFactory
.init(keyStore, pKeyPassword.toCharArray());
/*
* Trustore manager
*/
TrustManagerFactory trustManagerFactory = TrustManagerFactory
.getInstance("SunX509");
KeyStore trustStore = KeyStore.getInstance("JKS");
InputStream trustInput = new FileInputStream(new File(
cc.getWorkingDir() + File.separator
+ GSBConstants.TRUSTORE_NAME));
String pTrustPassword = GSBConstants.TRUSTORE_PASSWORD;
trustStore.load(trustInput, pTrustPassword.toCharArray());
trustInput.close();
trustManagerFactory.init(trustStore);
SSLContext context = SSLContext.getInstance("SSL");
context.init(keyManagerFactory.getKeyManagers(),
trustManagerFactory.getTrustManagers(),
new SecureRandom());
SSLContext.setDefault(context);
SSLSocketFactory sockFact = context.getSocketFactory();
con.setSSLSocketFactory(sockFact);
// Check for errors
int responseCode = con.getResponseCode();
InputStream inputStream;
if (responseCode == HttpURLConnection.HTTP_OK) {
inputStream = con.getInputStream();
} else {
inputStream = con.getErrorStream();
}
OutputStream output = new FileOutputStream("test.zip");
// Process the response
BufferedReader reader;
String line = null;
reader = new BufferedReader(new InputStreamReader(
inputStream));
while ((line = reader.readLine()) != null) {
output.write(line.getBytes());
}
output.close();
inputStream.close();
Any ideas ?
I don't have any exceptions.