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.
Related
I'm trying to log in to my server from my app with self-signed certificate. When I try to log in I get this error:
"Thread[6,tid=17486,WaitingInMainSignalCatcherLoop,Thread*=0xb4000074d0ac6570,peer=0x147c0000,"Signal Catcher"]: reacting to signal 3 "
"Wrote stack traces to tombstoned."
What could be the cause of that? I searched this error and found a few solutions but none worked.
Here is my code:
public class Connection extends AsyncTask{
#Override
protected Object doInBackground(Object[] objects) {
try {
Connect();
} catch (CertificateException | IOException | KeyStoreException | NoSuchAlgorithmException | KeyManagementException | NullPointerException e) {
e.printStackTrace();
ServerDirectActivity.response = true;
ServerDirectActivity.responseMsg = String.valueOf(e);
}
return null;
}
}
private void Connect() throws CertificateException, IOException, KeyStoreException, NoSuchAlgorithmException, KeyManagementException, NullPointerException {
CertificateFactory cf = CertificateFactory.getInstance("X.509");
HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() { #Override public boolean verify(String hostname, SSLSession session) { return true; } });
InputStream caInput = ServerDirectActivity.getmInstanceActivity().getAssets().open("client.csr");
Certificate ca = null;
try{
ca = cf.generateCertificate(caInput);
}catch (CertificateException e){
e.printStackTrace();
}finally {
caInput.close();
}
String keyStoreType = KeyStore.getDefaultType();
KeyStore keyStore = KeyStore.getInstance(keyStoreType);
keyStore.load(null, null);
keyStore.setCertificateEntry("ca", ca);
String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
tmf.init(keyStore);
context = SSLContext.getInstance("TLS");
context.init(null, tmf.getTrustManagers(), null);
URL url = new URL(serverIP);
HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection();
final String basicAuth = "Basic " + Base64.getEncoder().encodeToString((username + ":" + password).getBytes());
urlConnection.setRequestProperty("Authorization", basicAuth);
urlConnection.setSSLSocketFactory(context.getSocketFactory());
System.out.println(urlConnection.getResponseMessage());
System.out.println(urlConnection.getResponseCode());
if (urlConnection.getResponseCode() == 200){
InputStream in = urlConnection.getInputStream();
String line;
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
StringBuilder out = new StringBuilder();
while ((line = reader.readLine()) != null){
out.append(line);
}
System.out.println(out);
}
ServerDirectActivity.response = true;
ServerDirectActivity.responseMsg = String.valueOf(urlConnection.getResponseCode());
}
}
I have a java application that is making an HTTP DELETE to an external REST service. This error gets back to me from the server (running C#):
"Value cannot be null.\r\nParameter name: source\n at System.Linq.Enumerable.Count[TSource](IEnumerable`1 source)\r\n at AppCloud_Framework.Controllers.NotificationItemsController.DeleteNotificationItem(NotificationItem[] notificationItems) in C:\\Users\\jonas\\OneDrive\\VS Projects\\AppCloud Framework\\AppCloud Framework\\Controllers\\NotificationItemsController.cs:line 101\nValue:null"
The thing is, when I setup Postman to make the HTTP request to the same URL, with the same Payload and same HTTP method, the action is successful.
I do not have access to the server to investigate further so I need to find the resolution from the client side. Anyway it appears to be a client side issue.
I've been trying to find the problem myself but haven't succeeded. All I could come up with was to add "application/json" to Accept and Content-Type header properties.
My HTTP client:
public static Response execute(String url, Method method, String body) {
Response response = new Response();
try {
////////////////////////////////////////
// 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(X509Certificate[] certs, String authType) {
}
public void checkServerTrusted(X509Certificate[] certs, String authType) {
}
} };
// Install the all-trusting trust manager
final SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
// Create all-trusting host name verifier
HostnameVerifier allHostsValid = new HostnameVerifier() {
public boolean verify(String hostname, SSLSession session) {
return true;
}
};
// Install the all-trusting host verifier
HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
////////////////////////////////////////
URL urlObj = new URL(url);
HttpsURLConnection conn = (HttpsURLConnection) urlObj.openConnection();
conn.setInstanceFollowRedirects(false);
conn.setRequestMethod(method.toString());
conn.setRequestProperty("Content-Type", "application/json");
conn.setRequestProperty("Accept", "application/json");
//conn.setRequestProperty("Authorization", _authToken);
if (method == Method.POST || method == Method.PUT || method == Method.DELETE) {
conn.setDoOutput(true);
final OutputStream os = conn.getOutputStream();
os.write(body.getBytes());
os.flush();
os.close();
}
int status = conn.getResponseCode();
//log.info("HTTP request status code: "+status);
InputStream is;
if (status>399){
is = conn.getErrorStream();
}else{
is = conn.getInputStream();
}
if (is==null) return null;
BufferedReader rd = new BufferedReader(new InputStreamReader(is,
"UTF-8"));
String line;
while ((line = rd.readLine()) != null) {
response.body += line;
}
rd.close();
response.statusCode = conn.getResponseCode();
conn.disconnect();
} catch (Exception e) {
//log.error(e.getMessage());
e.printStackTrace();
System.out.println("");
response.exception = e.getMessage();
}
return response;
}
I am making a request with this body(disregard the encoding issue, source of that is somewhere else):
[{"hash":"150a17e99f67ce29fcc600c92eee831d","instanceid":"cb440a6f-44ef-4f05-ab41-143153655b6e","text":"{\"C_FirstAndLastName\":\"und\",\"ContactID\":\"1374231\",\"C_Fax\":\"\"}","queueDate":"2016-10-04T03:18:37"},{"hash":"1a94d9b5acff1a27dfe45be4ca5d9138","instanceid":"fdsfdsf-44ef-4f05-ab41-143153655b6e","text":"{\"C_FirstAndLastName\":\"J?รข??rgen\",\"ContactID\":\"323093\",\"C_Fax\":\"fsdfsd-B401-4AD3-AEA1-fdsfsdfsd\"}","queueDate":"2016-10-04T03:18:37"},{"hash":"8e592fb16d464bfd0f90f69818944198","instanceid":"fdsfsdf-44ef-4f05-ab41-143153655b6e","text":"{\"C_FirstAndLastName\":\"Claus\",\"ContactID\":\"2495844\",\"C_Fax\":\"fdsfsdgsd-304D-4E91-8586-fsdfsdfsd\"}","queueDate":"2016-10-04T03:18:37"},{"hash":"d6d226255e62690e50abbfa15c4b5462","instanceid":"cb440a6f-44ef-4f05-ab41-143153655b6e","text":"{\"C_FirstAndLastName\":\"Test J??rgen\",\"ContactID\":\"323093\",\"C_Fax\":\"fdsfsdfsd-B401-4AD3-AEA1-fdsfsdfsdf\"}","queueDate":"2016-10-04T03:18:49"}]
All I had to do was to define encoding in the output stream. Not sure if anyone could help me with that as I have just tried many things and some of it worked, but unfortunately nothing was pointing me into this direction.
os.write(body.getBytes("UTF-8"));
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"));
I want to do a HTTPS post method to send some data from my android app to my website.
I used HttpURLConnection first and it's working fine with my HTTP URL. My production website is on HTTPS and I want to send the same POST using HttpsURLConnection. Can someone help me use the class properly?
I found some source at this link:
KeyStore keyStore = ...;
TrustManagerFactory tmf = TrustManagerFactory.getInstance("X509");
tmf.init(keyStore);
SSLContext context = SSLContext.getInstance("TLS");
context.init(null, tmf.getTrustManagers(), null);
URL url = new URL("https://www.example.com/");
HttpsURLConnection urlConnection = (HttpsURLConnection)
url.openConnection();
urlConnection.setSSLSocketFactory(context.getSocketFactory());
InputStream in = urlConnection.getInputStream();
What should be the value of KeyStore keyStore = ...;?
I tried sending the data using the same HttpURLConnection, but I am seeing some POST data is missed or in error.
I've tried the method from this question. I am pasting my code below
String urlParameters="dateTime=" + URLEncoder.encode(dateTime,"UTF-8")+
"&mobileNum="+URLEncoder.encode(mobileNum,"UTF-8");
URL url = new URL(myurl);
HttpsURLConnection conn;
conn=(HttpsURLConnection)url.openConnection();
// Create the SSL connection
SSLContext sc;
sc = SSLContext.getInstance("TLS");
sc.init(null, null, new java.security.SecureRandom());
conn.setSSLSocketFactory(sc.getSocketFactory());
conn.setConnectTimeout(HTTP_CONNECT_TIME_OUT);
conn.setReadTimeout(HTTP_READ_TIME_OUT);
//set the output to true, indicating you are outputting(uploading) POST data
conn.setDoOutput(true);
//once you set the output to true, you don't really need to set the request method to post, but I'm doing it anyway
conn.setRequestMethod("POST");
conn.setFixedLengthStreamingMode(urlParameters.getBytes().length);
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
PrintWriter out = new PrintWriter(conn.getOutputStream());
out.print(urlParameters);
out.close();
InputStream is = conn.getInputStream();
BufferedReader in = new BufferedReader(new InputStreamReader(is));
String inputLine;
while ((inputLine = in.readLine()) != null) {
response += inputLine;
}
The error I am getting is below:
05-12 19:36:10.758: W/System.err(1123): java.io.FileNotFoundException: https://www.myurl.com/fms/test
05-12 19:36:10.758: W/System.err(1123): at libcore.net.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:177)
05-12 19:36:10.758: W/System.err(1123): at libcore.net.http.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:270)
05-12 19:36:10.758: W/System.err(1123): at .httpRequest(SMSToDBService.java:490)
05-12 19:36:10.758: W/System.err(1123): at com..access$0(SMSToDBService.java:424)
05-12 19:36:10.758: W/System.err(1123): at com.$ChildThread$1.handleMessage(SMSToDBService.java:182)
05-12 19:36:10.758: W/System.err(1123): at android.os.Handler.dispatchMessage(Handler.java:99)
05-12 19:36:10.758: W/System.err(1123): at android.os.Looper.loop(Looper.java:156)
05-12 19:36:10.758: W/System.err(1123): at com.$ChildThread.run(SMSToDBService.java:303)
You can use the default CAs that are defined in the android device, which is just fine for any public web.
If you have a self-signed certificate, you can either accept all certificates (risky, open to man-in-the-middle attacks) or create your own TrustManagerFactory, which is a bit out of this scope.
Here's some code to use the default CAs for a https POST call:
private InputStream getInputStream(String urlStr, String user, String password) throws IOException
{
URL url = new URL(urlStr);
HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
// Create the SSL connection
SSLContext sc;
sc = SSLContext.getInstance("TLS");
sc.init(null, null, new java.security.SecureRandom());
conn.setSSLSocketFactory(sc.getSocketFactory());
// Use this if you need SSL authentication
String userpass = user + ":" + password;
String basicAuth = "Basic " + Base64.encodeToString(userpass.getBytes(), Base64.DEFAULT);
conn.setRequestProperty("Authorization", basicAuth);
// set Timeout and method
conn.setReadTimeout(7000);
conn.setConnectTimeout(7000);
conn.setRequestMethod("POST");
conn.setDoInput(true);
// Add any data you wish to post here
conn.connect();
return conn.getInputStream();
}
To read the response:
String result = new String();
InputStream is = getInputStream(urlStr, user, password);
BufferedReader in = new BufferedReader(new InputStreamReader(is));
String inputLine;
while ((inputLine = in.readLine()) != null) {
result += inputLine;
}
You can take a look at this question I asked a few days ago:
Change HTTP post request to HTTPS post request:
I have supplied there a solution that worked for me, that basically accepts any self-signed certificate. As been said here this solution is not recommended as it's not secure and open to a man-in-the-middle attacks.
Here is the code:
EasySSLSocketFactory:
public class EasySSLSocketFactory implements SocketFactory, LayeredSocketFactory {
private SSLContext sslcontext = null;
private static SSLContext createEasySSLContext() throws IOException {
try {
SSLContext context = SSLContext.getInstance("TLS");
context.init(null, new TrustManager[] { new EasyX509TrustManager(null) }, null);
return context;
} catch (Exception e) {
throw new IOException(e.getMessage());
}
}
private SSLContext getSSLContext() throws IOException {
if (this.sslcontext == null) {
this.sslcontext = createEasySSLContext();
}
return this.sslcontext;
}
/**
* #see org.apache.http.conn.scheme.SocketFactory#connectSocket(java.net.Socket, java.lang.String, int,
* java.net.InetAddress, int, org.apache.http.params.HttpParams)
*/
public Socket connectSocket(Socket sock, String host, int port, InetAddress localAddress, int localPort,
HttpParams params) throws IOException, UnknownHostException, ConnectTimeoutException {
int connTimeout = HttpConnectionParams.getConnectionTimeout(params);
int soTimeout = HttpConnectionParams.getSoTimeout(params);
InetSocketAddress remoteAddress = new InetSocketAddress(host, port);
SSLSocket sslsock = (SSLSocket) ((sock != null) ? sock : createSocket());
if ((localAddress != null) || (localPort > 0)) {
// we need to bind explicitly
if (localPort < 0) {
localPort = 0; // indicates "any"
}
InetSocketAddress isa = new InetSocketAddress(localAddress, localPort);
sslsock.bind(isa);
}
sslsock.connect(remoteAddress, connTimeout);
sslsock.setSoTimeout(soTimeout);
return sslsock;
}
/**
* #see org.apache.http.conn.scheme.SocketFactory#createSocket()
*/
public Socket createSocket() throws IOException {
return getSSLContext().getSocketFactory().createSocket();
}
/**
* #see org.apache.http.conn.scheme.SocketFactory#isSecure(java.net.Socket)
*/
public boolean isSecure(Socket socket) throws IllegalArgumentException {
return true;
}
/**
* #see org.apache.http.conn.scheme.LayeredSocketFactory#createSocket(java.net.Socket, java.lang.String, int,
* boolean)
*/
public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException,
UnknownHostException {
return getSSLContext().getSocketFactory().createSocket(socket, host, port, autoClose);
}
// -------------------------------------------------------------------
// javadoc in org.apache.http.conn.scheme.SocketFactory says :
// Both Object.equals() and Object.hashCode() must be overridden
// for the correct operation of some connection managers
// -------------------------------------------------------------------
public boolean equals(Object obj) {
return ((obj != null) && obj.getClass().equals(EasySSLSocketFactory.class));
}
public int hashCode() {
return EasySSLSocketFactory.class.hashCode();
}
}
EasyX509TrustManager:
public class EasyX509TrustManager implements X509TrustManager {
private X509TrustManager standardTrustManager = null;
/**
* Constructor for EasyX509TrustManager.
*/
public EasyX509TrustManager(KeyStore keystore) throws NoSuchAlgorithmException, KeyStoreException {
super();
TrustManagerFactory factory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
factory.init(keystore);
TrustManager[] trustmanagers = factory.getTrustManagers();
if (trustmanagers.length == 0) {
throw new NoSuchAlgorithmException("no trust manager found");
}
this.standardTrustManager = (X509TrustManager) trustmanagers[0];
}
/**
* #see javax.net.ssl.X509TrustManager#checkClientTrusted(X509Certificate[],String authType)
*/
public void checkClientTrusted(X509Certificate[] certificates, String authType) throws CertificateException {
standardTrustManager.checkClientTrusted(certificates, authType);
}
/**
* #see javax.net.ssl.X509TrustManager#checkServerTrusted(X509Certificate[],String authType)
*/
public void checkServerTrusted(X509Certificate[] certificates, String authType) throws CertificateException {
if ((certificates != null) && (certificates.length == 1)) {
certificates[0].checkValidity();
} else {
standardTrustManager.checkServerTrusted(certificates, authType);
}
}
/**
* #see javax.net.ssl.X509TrustManager#getAcceptedIssuers()
*/
public X509Certificate[] getAcceptedIssuers() {
return this.standardTrustManager.getAcceptedIssuers();
}
}
And I added this method: getNewHttpClient()
public static HttpClient getNewHttpClient() {
try {
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
trustStore.load(null, null);
SSLSocketFactory sf = new MySSLSocketFactory(trustStore);
sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
HttpParams params = new BasicHttpParams();
HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);
SchemeRegistry registry = new SchemeRegistry();
registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
registry.register(new Scheme("https", sf, 443));
ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, registry);
return new DefaultHttpClient(ccm, params);
} catch (Exception e) {
return new DefaultHttpClient();
}
}
Finally for every place in my code that I had:
DefaultHttpClient client = new DefaultHttpClient();
I replace it with:
HttpClient client = getNewHttpClient();
Here's an Android HttpsUrlConnection POST solution complete with certificate pinning, timeouts server side code and configurations.
The variable params should be in the form username=demo&password=abc123&.
#Override
public String sendHttpRequest(String params) {
String result = "";
try {
URL url = new URL(AUTHENTICATION_SERVER_ADDRESS);
HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
connection.setSSLSocketFactory(KeyPinStore.getInstance().getContext().getSocketFactory()); // Tell the URLConnection to use a SocketFactory from our SSLContext
connection.setRequestMethod("POST");
connection.setDoOutput(true);
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
connection.setConnectTimeout(10000);
connection.setReadTimeout(10000);
PrintWriter out = new PrintWriter(connection.getOutputStream());
out.println(params);
out.close();
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()), 8192);
String inputLine;
while ((inputLine = in.readLine()) != null) {
result = result.concat(inputLine);
}
in.close();
//} catch (IOException e) {
} catch (IOException | KeyStoreException | CertificateException | KeyManagementException | NoSuchAlgorithmException e) {
result = e.toString();
e.printStackTrace();
}
return result;
}
I am using the code below to connect to https site. But the result is always a blank page. I have already searched alot. Any help will be appreciated.
public boolean shouldOverrideUrlLoading(WebView view, String url)
{ try
{
InputStream keyStoreStream = getResources().openRawResource(R.raw.jssecacerts);
KeyStore keyStore = null;
keyStore = KeyStore.getInstance("BKS");
keyStore.load(keyStoreStream, "mypwd".toCharArray());
KeyManagerFactory keyManagerFactory = null;
keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
keyManagerFactory.init(keyStore, "mypwd".toCharArray());
SSLContext context = SSLContext.getInstance("TLS");
context.init(keyManagerFactory.getKeyManagers(), null, null);
alertbox("before response", url);
URL url1 = new URL(url);
HttpsURLConnection urlConnection = (HttpsURLConnection) url1.openConnection();
urlConnection.setSSLSocketFactory(context.getSocketFactory());
InputStream in = urlConnection.getInputStream();
alertbox("response", convertToString(in));
view.loadData(convertToString(in), "text/html", "utf-8");
}
catch(Exception e)
{
e.printStackTrace();
}
return true;
}
have you tried something as simple as
webview.loadUrl("URL HERE");