简体   繁体   中英

SSL/TLS connection from android to a Custom Socket Server

Finished coding a simple Chat Server in erlang that uses gen_tcp (simple sockets) and an Android Client app for TESTING.

Now i need to implement SSL/TLS.

I kept connection (Sending and Receiving Data) part in a single module, a few lines of code that i can upgrade easily.

I have no prior experience of implementing SSL/TLS so i am confused here (like a lot).

Questions - Testing part (localhost):

I can generate self signed certificate by:

openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365

which results in two files, key.pem and cert.pem , My understanding is that one is Server certificate and the other is the key file but

  1. Where is Certificate Authority file? Do i need to generate one? Do i need one?
  2. Are they enough to test my app, to make it ready for a release?
  3. How do i turn my simple android socket into a secure socket? (kotlin preferred)
  4. Can i trust my self signed certificate programmatically (and only that one) or do i need to install it on my device (and any other device like a friend's device)

Questions - Production part:

  1. SHOULD i use my self signed certificate on my server? Do i need to create a CA? Pros and Cons of using self signed certificate?

  2. Can i use free certificates like from letsencrypt forever? Pros and Cons?

Finally:

  1. Do i need a certificate for Client too? Do i need to provide some sort of key[s] to Android app?

  2. What can i do to protect my app from MITM (or protect my app from revealing what is being sent/received to and from server) for exampleTHIS TYPE OF ATTACK

Since nobody answers, I will try to post my views on this:

Where is Certificate Authority file? Do i need to generate one? Do i need one?

You don't need to get your certificate signed by CA as long as the only server that your Android (or any other) client is going to use, is your own server. Server-side certificate is used by the server to prove its identity (ie to prove that it is really the one it pretends to be) to the clients, for example web browsers. So as long as your client connects to the same host (certificate of which it possesses beforehand), you don't need any signature (neither by CA nor self-signed)

Are they enough to test my app, to make it ready for a release?

Since you have used the most secure RSA (4096 bits), I can't see any other improvement that could be done to the certificate that you have generated, so yes you may consider it as ready for the release

How do i turn my simple android socket into a secure socket? (kotlin preferred)

I never used Kotlin, but in the Java environment, it is as easy as:

import javax.net.ssl.*;
import java.security.*;

SSLSocketFactory factory = (SSLSocketFactory)SSLSocketFactory.getDefault();
SSLSocket socket = (SSLSocket)factory.createSocket("host", port);

Can i trust my self signed certificate programmatically (and only that one) or do i need to install it on my device (and any other device like a friend's device)

You may add cert.pem into a keystore file (assuming store type is JKS and password is passw ):

keytool -importcert -file cert.pem -keystore keystore.jks -storetype JKS -alias "alias" -storepass passw

and then put keystore.jks into raw folder of your app thus making it accessible as R.raw.keystore from within your code:

    KeyStore trusted = KeyStore.getInstance("JKS");
    InputStream in = context.getResources().openRawResource(R.raw.keystore); //open inputstream for keystore file in "raw" folder
    trusted.load(in, "passw".toCharArray());                                 //load the keystore from file (using password specified when certificate was imported into keystore)       
    in.close();                                                              //close inputstream 
    KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
    kmf.init(trusted, "passw".toCharArray());
    SSLContext sslContext = SSLContext.getInstance("TLSv1.2");               //configure SSL Context to use TLS v1.2 
    sslContext.init(kmf.getKeyManagers(),null,null);
    SSLSocketFactory factory = sslContext.getSocketFactory();

and then you use factory in the way described above to open secure sockets

SHOULD i use my self signed certificate on my server? Do i need to create a CA? Pros and Cons of using self signed certificate?

See answer 1

Can i use free certificates like from letsencrypt forever? Pros and Cons?

It all depends on how big is the risk of a particular CA to get compromised ie sign a fraudulent certificate. It is always better to use a trustworthy CA though at a higher cost

Do i need a certificate for Client too? Do i need to provide some sort of key[s] to Android app?

Client certificate is just another way of authenticating the end user. If you already use a password for authentication, you don't need to use a client certificate (you may actually add it for additional security but mostly it is not necessary, besides someone may steal it)

What can i do to protect my app from MITM (or protect my app from revealing what is being sent/received to and from server) for example THIS TYPE OF ATTACK

Well, it is fine as long as the device belongs to its original owner. The risk arises in case if it is stolen and the thief is aware of that proxy and may reveal the request/response contents. Nothing else comes to my mind other than the user changing his/her password as soon as possible

The accepted answer is good but incomplete.

Where is Certificate Authority file? Do i need to generate one? Do i need one?

It is a part of Public Key Infrastructure. The word "public" is of interest here: if your server is not going to be used by anyone but you, then it does not make a whole lot of sense to pay for a third-party CA certificate. These are meant for domains that are deployed for a vast number of public users, and hence subject to attacks & vulnerabilities.

SHOULD i use my self signed certificate on my server? Do i need to create a CA? Pros and Cons of using self signed certificate?

Now here comes the pickle: if you use a third-party CA certificate, it will cost money, but it can be accessed publicly by mobile devices and browsers out of the box, ie the default SSL socket factory will be able to connect with your domain.

If you opt for a self-signed certificate, a mobile device or browser cannot fulfil the SSL handshake (ie it cannot connect) with your domain without one of the below changes:

  • instruct your socket factory to ignore SSL validation .
  • create a socket factory that recognizes your certificate
  • add the self-signed certificate you created to the list of known certificates on your client device (mobile/desktop browser).
  • use a technique called SSL pinning to test handshakes & connections.

Do i need a certificate for Client too? Do i need to provide some sort of key[s] to Android app?

What you're talking about is referred to as Bidirectional or Two-Way SSL validation . This is good but optional. It is necessary and sufficient to have a publicly known CA certificate on your server.

How do i turn my simple android socket into a secure socket?

The default socket IS the secure socket, at least with any sane TCP/HTTP library. You have to make code changes to tell the socket factory to ignore SSL validation.

Are they enough to test my app, to make it ready for a release?

Well, this is a bit unclear. You should test using SSL pinning or a known CA certificate, not with a self-signed certificate. If you want to test just your app functionality, you can disable SSL validation. And a release app, as I understand it, will require the default (ie secure) socket factory that automatically manages SSL handshakes with a recognized third-party CA certificate.

Can i trust my self signed certificate programmatically (and only that one) or do i need to install it on my device (and any other device like a friend's device)

Yes, it can be installed on the client device / browser. But then your server can only be communicated with from THAT device / browser.

Last point :

If you publish an app on the Play Store with a self-signed certificate, or with SSL validation disabled or ignored, you will soon receive an email warning that your app will be taken down. Good luck.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM