This question already has an answer here:
Embedded Jetty with client certificates
(1 answer)
Closed 8 years ago.
Hello I have a question regarding enabling embedded jety with https and ssl. I am completely dummy regarding this issue.
I want to follow this code:
http://www.smartjava.org/content/embedded-jetty-client-certificates
but I need to have server and client keystore. I have followed this:
http://www.eclipse.org/jetty/documentation/current/configuring-ssl.html#generating-csr-from-openssl
to generate the keys but I have no idea how to use them and on the other hand I am not sure if that's that I want.
any idea? by the way my jetty version is 8.
Thanks!
Once I had some problem with ssl websites to download stuff from it.
I dont know its the same problem but I could make this trusted object. And with it I can manage the https connection and download:
// Create a new trust manager that trust all certificates
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) {
}
}
};
// Activate the new trust manager
try {
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
} catch (Exception e) {
}
URL url = new URL(src);
URLConnection connection = url.openConnection();
InputStream is = connection.getInputStream();
BufferedImage bufImgOne = ImageIO.read(url);
ImageIO.write(bufImgOne, "jpg", new File("test.jpg"));
if its not the solution just or almost please write than i try to help
or simply delete to not spam your thread
Related
I am calling API to login but I am getting error of ssl handshake in Android 7.0, other than this version everything is working fine. I am using retrofit.
Following is the error.
SSL handshake terminated: ssl=0xcbcd0340: Failure in SSL library, usually a protocol error
error:1000043e:SSL routines:OPENSSL_internal:TLSV1_ALERT_INAPPROPRIATE_FALLBACK (external/boringssl/src/ssl/s3_pkt.c:610 0xebc87640:0x00000001)
Also as said by someone to add the following code so that this issue will be resolved but still no luck,
ConnectionSpec spec = new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)
.tlsVersions(TlsVersion.TLS_1_2)
.cipherSuites(
CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
CipherSuite.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256)
.build();
okHttpClient.connectionSpecs(Collections.singletonList(spec));
I have even tried to letgo trust each and every certificate but still no luck. Following is the code.
public static OkHttpClient.Builder sslSocketFactory(OkHttpClient.Builder okHttpClient)
{
try {
// Create a trust manager that does not validate certificate chains
final TrustManager[] trustAllCerts = new TrustManager[]{
new X509TrustManager() {
#Override
public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
}
#Override
public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
}
#Override
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return new java.security.cert.X509Certificate[]{};
}
}
};
ConnectionSpec spec = new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)
.tlsVersions(TlsVersion.TLS_1_0)
.allEnabledCipherSuites()
.build();
// Install the all-trusting trust manager
final SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
// Create an ssl socket factory with our all-trusting manager
final javax.net.ssl.SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
//////// OkHttpClient.Builder builder = new OkHttpClient.Builder();
okHttpClient.sslSocketFactory(sslSocketFactory, (X509TrustManager) trustAllCerts[0]);
okHttpClient.hostnameVerifier(new HostnameVerifier() {
#Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
});
return okHttpClient;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
Following are my ssllabs tested using android 7.0
ssllabs test
In all other android versions all API's are working fine I do get response, but I am not able to get response in version 7.0.
Actually it's more likely to be a ssl_ciphers server-side settings problem.
Assuming nginx, change your ssl_ciphers settings to the one recommended by openHab :
ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:HIGH:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!CBC:!EDH:!kEDH:!PSK:!SRP:!kECDH;
Don't forget to reload (systemctl reload nginx) and now all problematic android devices should work just fine.
I am developing an Android application under Android Studio and I need to establish HTTPS connection. So far I've succeeded, but with current implementation I am trusting all hosts, which could easily lead to man-in-the-middle attack. So I was wondering is there a way to trust an exact certificate and no other? So far my code looks like this:
/**
* Trust every server - dont check for any certificate
*/
private void trustAllHosts() {
// Create a trust manager that does not validate certificate chains
TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return new java.security.cert.X509Certificate[]{};
}
public void checkClientTrusted(X509Certificate[] chain,String authType) throws CertificateException {
}
public void checkServerTrusted(X509Certificate[] chain,String authType) throws CertificateException {
}
}};
// Install the all-trusting trust manager
try {
SSLContext sc = SSLContext.getInstance("TLS");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
} catch (Exception e) {
e.printStackTrace();
}
}
And I am using HttpsURLConnection like this:
private void postText(String URLAddress) {
try {
URL obj = new URL(URLAddress);
HttpsURLConnection con = (HttpsURLConnection) obj.openConnection();
con.setHostnameVerifier(DO_NOT_VERIFY);
con.setRequestMethod("POST");
con.setRequestProperty("User-Agent", "Mozilla/5.0");
int responseCode = con.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) { //success
BufferedReader in = new BufferedReader(new InputStreamReader(
con.getInputStream()));
String inputLine;
StringBuilder response = new StringBuilder();
boolean First = true;
while ((inputLine = in.readLine()) != null) {
if(First)
First=false;
else
response.append("\n");
response.append(inputLine);
}
in.close();
RequestResponse=response.toString();
}
} catch (Exception e) {
e.printStackTrace();
}
}
What should I do to be able to trust only the certificate that I want? What information for that certificate do I need and what I must use in order to achive this?
Thanks
If you want to handle the verification yourself the easy part is to pin the public key. But then you have to think about the revocation and then your problems starts.
Why not simply using a certificate trusted by the device?
What should I do to be able to trust only the certificate that I want?
The process of trusting only a specific certificate or public key is called certificate pinning or public key pinning. Since I don't want to repeat all the good information which already exist: please head over to the specific article at OWASP which also includes sample code for Android.
And in case this link goes down or moves - just search for android certificate pinning example.
The correct way to do this is to verify the identity of the subject of the certificate as being the identity that is authorized to be connected to, rather than abuse the authentication process as you are doing by trusting a single certificate, which among other things gives you a problem at renewal time.
At the SSL level this is done by installing a handshake listener.
At the HTTPS level this is done by installing a HostnameVerifier.
My scope is to send an https message trusting all certificates from a Java application on an Embedded Linux Module with a JVM (IcedTea6 1.11, Java Version 1.6.0_24) on it (as Info I have no access to this Embedded Linux or to the JVM to make any changes, I can only put compiled java application on it).
I have only basic Java knowledge but I wrote from some examples found on the net an application that trust all certificates.
At the beginning I had an error on the line
SSLContext sc = SSLContext.getInstance("SSL");
and I found out that the problem was that the SunJSSE Provider was not implemented in the JVM.
My first step was to add the SunJSSE Provider
Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
and after this if I read out the providers I can see that the adding was successfully and now I find the provider “SunJSSE version 1.6”.
The Trust all Certificate Class is as following:
public final class TrustAllCertificates implements X509TrustManager, HostnameVerifier
{
public X509Certificate[] getAcceptedIssuers() {return null;}
public void checkClientTrusted(X509Certificate[] certs, String authType) {}
public void checkServerTrusted(X509Certificate[] certs, String authType) {}
public boolean verify(String hostname, SSLSession session) {return true;}
public static void install()
{
try
{
TrustAllCertificates trustAll = new TrustAllCertificates();
final SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, new TrustManager[]{trustAll}, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
HttpsURLConnection.setDefaultHostnameVerifier(trustAll);
}
catch (Exeption e)
{
JatLog.writeTempLog("Error: " + e.getMessage());
}
}
}
Now I receive always the error
access denied (java.lang.RuntimePermission setFactory)
On executing the line
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
Someone has any idea about how to solve this?
looks like the SecurityManager blocks this. Try settings for a single connection:
SSLContext sc = SSLContext.getInstance("SSL");
TrustAllCertificates trustAll = new TrustAllCertificates();
sc.init(null, new TrustManager[] { trustAll }, new java.security.SecureRandom());
URL url = new URL("https://www.google.com/");
URLConnection urlConnection = url.openConnection();
if (urlConnection instanceof HttpsURLConnection) {
HttpsURLConnection uc = (HttpsURLConnection) urlConnection;
uc.setSSLSocketFactory(sc.getSocketFactory());
uc.setHostnameVerifier(trustAll);
uc.connect();
JatLog.writeTempLog("headers: "+uc.getHeaderFields());
uc.disconnect();
}
if that doesnt help ask the swedish guys to update security manager settings ;)
hth
I have been working on a java activemq client software to connect to a ssl powered broker, but setting the trust store programatically through:
// Configure the secure connection factory.
ActiveMQSslConnectionFactory connectionFactory = new ActiveMQSslConnectionFactory(url);
connectionFactory.setTrustStore("/conf/client.ts"); // truststore which includes the certificate of the broaker
connectionFactory.setTrustStorePassword("password");
as indicated here. However, that throw a
javax.net.ssl.SSLHandshakeException:
sun.security.validator.ValidatorException: PKIX path building failed
Error
Following the response of the QA Resolving javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed Error? I was able to successfully connect the client to the broker by adding the broker certificate to my java installation's trusted certificates.
However, in this case, I do not want each user using the application to import the certificate on their java distribution, but rather that the client application already carries the broker certificate. How can I do that preferably using the ActiveMQSslConnectionFactory class?
From what I understand, you need to trust all the incoming self-signed certificates.
You could try this way (create a trust-manager which does not validate and then register it:
TrustManager[] trustAllCerts = new TrustManager[] {
new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(
java.security.cert.X509Certificate[] certificates, String authType) {
}
public void checkServerTrusted(
java.security.cert.X509Certificate[] certificates, String authType) {
}
}
};
try {
SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
} catch (GeneralSecurityException e) {
}
//then do the ssl conversation.
I still havent managed to set the truststore programattically using the setTrustStore method from ActiveMQSslConnectionFactory
But based on #Chris response, it was possible to attach a new trust manager which accept all certificates to the ActiveMQSslConnectionFactory.
In order to do so, I created the same TrustManager as him, but used a different method to link it to the ActiveMQSslConnectionFactory
TrustManager[] trustAllCerts = new TrustManager[] {
new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(
java.security.cert.X509Certificate[] certificates, String authType) {
}
public void checkServerTrusted(
java.security.cert.X509Certificate[] certificates, String authType) {
}
}
};
try {
String connectionString = "ssl://ipaddress:port"
ActiveMQSslConnectionFactory factory = new ActiveMQSslConnectionFactory(connectionString);
factory.setKeyAndTrustManagers(null, trustAllCerts, new SecureRandom());
Connection connection = factory.createConnection(user,password);
connection.start();
} catch (Exception e) {
}
I've been testing a system that accesses a group of https servers with different keys, some of which are invalid and all of them are not in the local key store for my JVM. I am really only testing things out, so I don't care about the security at this stage. Is there a good way to make POST calls to the server and tell Java not to worry about the security certificates?
My google searches for this have brought up some code examples that make a class to do the validation, that always works, but I cannot get it to connect to any of the servers.
As per the comments:
With Googled examples, you mean among others this one?
Update: the link broke, so here's an extract of relevance which I saved from the internet archive:
// Create a trust manager that does not validate certificate chains
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) {
}
}
};
// Install the all-trusting trust manager
try {
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
} catch (Exception e) {
}
// Now you can access an https URL without having the certificate in the truststore
try {
URL url = new URL("https://hostname/index.html");
} catch (MalformedURLException e) {
}
You need to create a X509TrustManager which bypass all the security check. You can find an example in my answer to this question,
How to ignore SSL certificate errors in Apache HttpClient 4.0