1

According to the Android Documentation:

Assuming you have a web server with a certificate issued by a well known CA, you can make a secure request with code as simple this:

URL url = new URL("https://wikipedia.org");
URLConnection urlConnection = url.openConnection();
InputStream in = urlConnection.getInputStream();
copyInputStreamToOutputStream(in, System.out);

Yes, it really can be that simple.

I am currently working on an Android project and now want to start introducing a User System (DataBase of users/passwords, registration/log in capabilities, etc.).

Here is how we are currently handling the connection (in the Android section of the project):

package com.example.payne.simpletestapp;


import org.osmdroid.util.BoundingBox;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;


public class ServerConnection {

    public String serverAddress;
    public int port;

    public ServerConnection(String addr, int port){
        this.serverAddress = addr;
        this.port = port;

    }

    public ServerConnection(String addr){

        this.port = 80;
        this.serverAddress = addr;

    }

    /**
     * Envoie une requête au serveur de façon périodique.
     * <p></p>
     * Reçoit toutes les alertes sur le territoire
     *
     * @return
     */
    public String ping(BoundingBox boundingBox) throws Exception {

        String param =
            "?nord=" + boundingBox.getLatNorth() +
            "&sud=" + boundingBox.getLatSouth() +
            "&est=" + boundingBox.getLonEast() +
            "&ouest=" + boundingBox.getLonWest();

        return this.getRequest("/alertes", param);

    }


    public String getRequest(final String path, final String param) throws Exception {

        final Response result = new Response();

        Thread connection = new Thread(new Runnable() {

            @Override
            public void run() {

                try{
                    URL obj = new URL(serverAddress + path + param);
                    HttpURLConnection con = (HttpURLConnection) obj.openConnection();

                    // optional default is GET
                    con.setRequestMethod("GET");
                    // int responseCode = con.getResponseCode();

                    BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
                    String inputLine;
                    StringBuffer response = new StringBuffer();

                    while ((inputLine = in.readLine()) != null) {
                        response.append(inputLine);
                    }

                    in.close();

                    result.response = response.toString();

                } catch (Exception e){
                    e.printStackTrace();
                }
            }
        });

        connection.start();
        connection.join();


        return result.response;

    }

    public Boolean postAlert(Alerte alerte) {

        boolean success = false;
        alerte.log();

        String param =  "?type=" + alerte.type +
                        "&lat=" + alerte.getLatitude() +
                        "&lng=" + alerte.getLongitude();

        try {
            this.getRequest("/putAlert", param);
            success = true;
        } catch (Exception e) {
            e.printStackTrace();
        }

        return success;

    }


}

Note that elsewhere, another member of the team seems to have been establishing connections differently (in the 'backend' section of the project, which is used by the server, and not necessarily by Android):

private String getRssFeed() {
    try {
        String rss = "";
        URL rssSource = new URL("https://anURLwithHTTPS.com/");
        URLConnection rssSrc = rssSource.openConnection();
        BufferedReader in = new BufferedReader(
                new InputStreamReader(
                        rssSrc.getInputStream(), StandardCharsets.UTF_8));
        String inputLine;

        while ((inputLine = in.readLine()) != null) {
            rss += inputLine;
        }

        in.close();

        String rssCleaned = rss.replaceAll("&lt;", "<").replaceAll("&gt;", ">").substring(564);

        return rssCleaned;
    } catch (MalformedURLException ex) {
        Logger.getLogger(AlertesFluxRss.class.getName()).log(Level.SEVERE, null, ex);
    } catch (IOException ex) {
        Logger.getLogger(AlertesFluxRss.class.getName()).log(Level.SEVERE, null, ex);
    }
    return "";
}

The questions are:

  1. Will the first code presented (the Android-related one) use an encrypted connection (HTTPS)?
  2. What about the second one?
  3. How do we test if the information that was sent is encrypted?
  4. Is casting to HttpURLConnection a threat? The documentation seems to indicate that it would automatically recast into "HttpsURLConnection".
  5. Since HttpsURLConnection extends HttpURLConnection, it has all of the capacities HttpURLConnection and more, right?

I did find this, but it wasn't exactly what I was looking for.

Our current idea for registering new users would be to send their information within an URL through en encrypted connection (along the lines of https://myWebsite.com/api/?user=Bob&pass=amazing) to the server (hosted on https://www.heroku.com).

If there are better ways to do such a thing, please let me know. Suggestions will be gladly considered. I'm not too knowledgeable when it comes to Libraries neither, so please share anything you know that might make my approach more secure and fast to implement.

Thank you so much for your help in advance! :)

payne
  • 4,691
  • 8
  • 37
  • 85
  • Why would you even suspect that the Android code would use an HTTPS connection? There no hint of it that I can see. Please keep your questions narrow. This one is too broad. – President James K. Polk Jun 03 '18 at 21:36
  • The Documentation linked seemed to hint at that. (Bare in mind, English is not my native language.) Also, I have seen so many users being requested to post complete pieces of code before receiving help that I thought I would share everything one might need to help me out. What exactly is superfluous here? (Sorry, this is my first question asked on StackOverflow... I've only ever been a lurker before.) – payne Jun 03 '18 at 22:19

1 Answers1

1

Will the first code presented (the Android-related one) use an encrypted connection (HTTPS)?

Not without seeing the URL the 'first code presented' uses, which isn't shown. In the Android sample you quoted, the URL string "https://wikipedia.org" guarantees it, by definition. If it starts with https:, it uses HTTPS, which is encrypted: otherwise, it doesn't, and isn't.

What about the second one?

Yes, for the reason given above.

How do we test if the information that was sent is encrypted?

You don't. You use an https: URL. The rest is automatic. It works. Worked for 22 years. No testing required. Don't test the platform. If you must check it, attempt a typecast to HttpsURLConnection. If it's HTTPS, that will succeed: otherwise, fail.

Is casting to HttpURLConnection a threat?

No. I don't understand why you ask.

The documentation seems to indicate that it would automatically recast into "HttpsURLConnection".

No it doesn't. It indicates than an HttpsURLConnection is created. No casting.

Since HttpsURLConnection extends HttpURLConnection, it has all of the capacities HttpURLConnection and more, right?

Right.

user207421
  • 305,947
  • 44
  • 307
  • 483
  • Thank you for the answer! From the first piece of code: `HttpURLConnection con = (HttpURLConnection) obj.openConnection();` My understanding is that "con" would be created as a "HttpsURLConnection" but only have the functionalities of "HttpURLConnection" due to the cast; am I right in believing so? (That was the point of my question about the "threat of casting", to clarify.) EDIT: Assuming the URL contains the "https" header. – payne Jun 04 '18 at 01:16
  • Furthermore, I would like to ensure that the way we plan on doing the registration is safe: the encrypted layer HTTPS uses would not necessarily hide the domain name, but the subsequent information of the posted URL-Request would be encrypted (username and password, in my case)? Thus, `https://mywebsite.com/api/?user=Bob&pass=amazing` would reveal only "https://mywebsite.com/". – payne Jun 04 '18 at 01:19
  • Lastly, I looked into your history and have figured out you seem to be a very knowledgeable person when it comes to this subject. I will most probably mark your answer as "Accepted", but I would love it if you could provide official sources related to your claims (for posterity and verification). :) – payne Jun 04 '18 at 01:25
  • The connection object is an `HttpsURLConnection`. The *reference variable you are storing it in* has type `HttpURLConnection`, so you can only use methods of `HttpURLConnection` via it. This is rather basic, 'Threat of casting' is meaningless. Your remark about DNS and subsequent encryption is correct. You don't need primary sources for things that are true by definition. If an `https:` URL wasn't encrypted it would be treated as a serious bug in the platform. That is the whole intent of the scheme. – user207421 Jun 04 '18 at 01:28
  • I guess my concern is that the protocol that encrypts might only be available to HTTPS-type connections (thus those "methods" might only be part of the "HttpsURLConnection" class), hence the possibility of the absence of the "encryption" features. (Keep in mind, I'm am not too educated when it comes to Internet-related protocols.) – payne Jun 04 '18 at 01:38
  • There is no 'absence of the encryption features'. You just have a downcast *reference.* The *object* is an `HttpsURLConnection`. Downcasting to the reference type doesn't change the object. This has nothing to do with Internet-related protocols. It is basic Java. – user207421 Jun 04 '18 at 01:51