0

I am trying to connect Azure SQL Database using Android Application, While connecting to the Azure SQL database, I am getting SSL Handshake aborted issue. I am using the latest android studio 4.1.2 version and the Android Version was Lollipop 5.0. and also I added a TLS certificate to the application.

Any idea how to fix it ??

Here is my java code :

public static void SetUpHttpsConnection(String urlString) {
        String response = null;
        try {
            CertificateFactory cf = CertificateFactory.getInstance("X.509");

            System.out.println("Loading Certificate from Assets folder ....");
            InputStream caInput = new BufferedInputStream(MainActivity.context.getAssets().open("ca-bundle.crt"));

            X509Certificate caCertificate = (X509Certificate) cf.generateCertificate(caInput);
            Certificate ca = cf.generateCertificate(caInput);
            System.out.println("generate certificate .............");
            System.out.println("ca : " + (caCertificate).getSubjectDN());

            // Create a KeyStore containing our trusted CAs
            String keyStoreType = KeyStore.getDefaultType();
            KeyStore keyStore = KeyStore.getInstance(keyStoreType);
            keyStore.load(null, null);
            keyStore.setCertificateEntry("ca", caCertificate);

            // Create a TrustManager that trusts the CAs in our KeyStore
            String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
            TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
            System.out.println(" Trust Manager Factory ------ ");
            tmf.init(keyStore);

            // Create an SSLContext that uses our TrustManager
             SSLContext context1 = SSLContext.getInstance("TLS");
            //SSLContext context1 = SSLContext.getInstance("TLSv1.2");
            System.out.println(" ------------------------------- ");
            //context1.init(null, tmf.getTrustManagers(), null);
            System.out.println("SSL context ---- :" + context1);

            context1.init(null, new X509TrustManager[]{new X509TrustManager(){
                @SuppressLint("TrustAllX509TrustManager")
                public void checkClientTrusted(X509Certificate[] chain,
                                               String authType) throws CertificateException {}
                @SuppressLint("TrustAllX509TrustManager")
                public void checkServerTrusted(X509Certificate[] chain,
                                               String authType) throws CertificateException {}
                public X509Certificate[] getAcceptedIssuers() {
                    return new X509Certificate[0];
                }}}, new SecureRandom());
            HttpsURLConnection.setDefaultSSLSocketFactory(
                    context1.getSocketFactory());
            System.out.println("Trust Certificates ----- ");

            // Tell the URLConnection to use a SocketFactory from our SSLContext
            URL url = new URL(urlString);
            HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection();
            if (urlConnection instanceof HttpsURLConnection) {
                HttpsURLConnection httpsConn = (HttpsURLConnection) urlConnection;
                httpsConn.setSSLSocketFactory(SSLCertificateSocketFactory.getInsecure(0,null));
                httpsConn.setHostnameVerifier(new AllowAllHostnameVerifier());
                httpsConn.setRequestProperty("Connection", "Keep-Alive");
                httpsConn.setRequestProperty("Charset", "UTF-8");
            }

            urlConnection.setRequestMethod("GET");
            urlConnection.setConnectTimeout(2500);
            urlConnection.setReadTimeout(3500);
            urlConnection.setRequestProperty("Content-Type", "application/json");

            int statuscode = urlConnection.getResponseCode();
            Log.d("Status code :", Integer.toString(statuscode));

            InputStream inputStream = urlConnection.getInputStream();
            if (inputStream != null) {
                response = streamToString(inputStream);
                inputStream.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static String readStream(InputStream is) throws IOException {
        final BufferedReader reader = new BufferedReader(new InputStreamReader(is, Charset.forName("US-ASCII")));
        StringBuilder total = new StringBuilder();
        String line;
        while ((line = reader.readLine()) != null) {
            total.append(line);
        }
        if (reader != null) {
            reader.close();
        }
        return total.toString();
    }

    private static String streamToString(InputStream inputStream) throws IOException {
        StringBuffer sb = new StringBuffer();
        BufferedReader rd = new BufferedReader(new InputStreamReader(inputStream));
        String line;
        while ((line = rd.readLine())!= null) {
            sb.append(line);
        }
        return sb.toString();
    }

    @SuppressLint("StaticFieldLeak")
      private class Azure_Connection extends AsyncTask<String, Void, Iterable<Test>> {
          String res = "";
          private String rowKey;

          @Override
          protected void onPreExecute() {
              super.onPreExecute();
              Toast.makeText(MainActivity.this, "Please wait...", Toast.LENGTH_SHORT)
                      .show();
          }

          protected Iterable<Test> doInBackground(String... arg0) {
              try {
                  Class.forName("net.sourceforge.jtds.jdbc.Driver").newInstance();
                  System.out.println("Reading JDBC Driver");

                  String UserName = "username@iwavesqlserver";
                  String Passwrd = "*******";

                     String ConnectionString = "jdbc:jtds:sqlserver://iwavesqlserver.database.windows.net:1433/iwave_db_1;loginTimeout=300;ssl=require;" +
"integratedSecurity=true;encrypt=false;TrustServerCertificate=true;hostNameInCertificate=*.database.windows.net;";

                  System.out.println(" .......... Connecting to the SQL Database .......... ");
                  String urlString = "https://portal.azure.com/#home";
                  SetUpHttpsConnection(urlString);

                  try {
                       Connection connection = DriverManager.getConnection(ConnectionString, UserName, Passwrd);
                      if (connection != null) {
                          System.out.println("Database connection success");
                      }
                      Statement stmt = Objects.requireNonNull(connection).createStatement();
                      ResultSet resultSet = stmt.executeQuery("SELECT * FROM test");
                      log.info("Database Connection test : " + connection);
                  } catch (SQLException e) {
                      e.printStackTrace();
                  }
              }catch (Exception e) {
                  System.out.println(e.getMessage());
              }
              return null;
          }
      }

Error message :

I/System.out:  Connection Exception : java.sql.SQLException: Network error IOException: SSL handshake aborted: ssl=0xebc432c8: I/O error during system call, Broken pipe
W/System.err: java.sql.SQLException: Network error IOException: SSL handshake aborted: ssl=0xebc432c8: I/O error during system call, Broken pipe
W/System.err:     at net.sourceforge.jtds.jdbc.JtdsConnection.<init>(JtdsConnection.java:436)
W/System.err:     at net.sourceforge.jtds.jdbc.Driver.connect(Driver.java:184)
        at java.sql.DriverManager.getConnection(DriverManager.java:569)
W/System.err:     at java.sql.DriverManager.getConnection(DriverManager.java:219)
        at com.iwavesys.cloudazure.MainActivity$Azure_Connection.doInBackground(MainActivity.java:381)
        at com.iwavesys.cloudazure.MainActivity$Azure_Connection.doInBackground(MainActivity.java:316)
W/System.err:     at android.os.AsyncTask$2.call(AsyncTask.java:333)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
W/System.err:     at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:245)
W/System.err:     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
        at java.lang.Thread.run(Thread.java:764)
W/System.err: Caused by: javax.net.ssl.SSLHandshakeException: SSL handshake aborted: ssl=0xebc432c8: I/O error during system call, Broken pipe
        at com.android.org.conscrypt.NativeCrypto.SSL_do_handshake(Native Method)

I am not sure this is the correct way to add certificates and get a connection to the Azure SQL database. please anyone help me to solve this issue.

Thank you.

vasi
  • 1
  • 3

0 Answers0