3

I have an Android app that communicates with my host server. The app and the server communicates thru SSL. Every year, I have to renew the (self-signed) certificate in the host server. Every time that cert expires, I have to update my Android app accordingly by creating my own TrustManager and trusting the new certificate directly. This is working perfectly.

The thing is, I don't want to modify my Android app every time my cert expires. So the question is, how do I trust all the self-signed certificates that I issue? Again, only the self-signed certificates from me.

These are the restrictions:

  1. Only self-signed certs can be used
  2. I can only create new certs valid for 12 months max

This is how I generate the cert:

openssl req -newkey rsa:4096 \
        -x509 \
        -sha256 \
        -days 365 \
        -nodes \
        -out selfSignedCert.crt \
        -keyout newPrivate.key

Would appreciate your help.

user1506104
  • 6,554
  • 4
  • 71
  • 89

2 Answers2

6

Create a CA cert with 10 years validity. Sign the server cert with CA cert. Server cert should have 1 year or less validity. In your application include the CA cert and add it in your custom TrustManager. Now you only need to release new app every 10 years when CA cert expires. Your TrustManager should accept all certs which are signed by your CA cert.

Details steps : 1. Create the CA key

    sudo openssl genrsa -out  CA/rocketCA.key 1024
  1. Create a CA certificate Request
    openssl req -new -key CA/rocketCA.key -out CA/rocketCA.csr
  1. Self sign the CA certificate
    sudo openssl x509 -req -days 3650 -in CA/rocketCA.csr -out CA/rocketCA.crt -signkey CA/rocketCA.key
  1. Verify the CA certificate contents
    openssl x509 -in CA/hitenCA.crt -text
  1. create the web server private key using a fully qualified DNS name such as rocket.example.com OR use IPAddress. When prompted for the pass phrase, enter a password that you can remember.
    sudo openssl genrsa -des3 -out server/keys/rocket.example.com.key 1024
  1. create the web server certificate request using the same fully qualified DNS name/IP you used for the private key
    openssl req -new -key server/keys/rocket.example.com.key -out server/requests/rocket.example.com.csr
  1. sign the web server certificate with the CA key
    sudo openssl ca -days 3650 -in server/requests/rocket.example.com.csr -cert CA/rocketCA.crt -keyfile CA/rocketCA.key -out server/certificates/rocket.example.com.crt
  1. To verify the web server certificate contents, use the following command
    openssl x509 -in server/certificates/rocket.example.com.crt -text

Key values to look for are:

Subject CN=rocket.example.com
Issuer CN=rocketCA

Reference for detailed steps : (You do not need the Mutual Auth part)

http://www.cafesoft.com/products/cams/ps/docs32/admin/ConfiguringApache2ForSSLTLSMutualAuthentication.html

RocketRandom
  • 1,102
  • 7
  • 20
  • Thanks. I will take a look asap. By the way, StackOverflow discourages link-only answers because links become invalid after a few months or years. You might want to copy the detailed steps in your answer and provide the link as a reference. – user1506104 Feb 27 '20 at 06:27
  • Okay I will do that. – RocketRandom Feb 27 '20 at 07:10
3

First, it is unclear why exactly you have a limit of one year and how exactly you issue a new certificate and why you are restricted to self-signed certificates only. But the common way to do a pinning/trusting which still works with a renewed certificate is to pin against the public key of the certificate and not against the certificate itself. Then make sure that the key stays the same when renewing the certificate.

Steffen Ullrich
  • 114,247
  • 10
  • 131
  • 172
  • Thank you. I updated my question to include how I generate the certificate. However, checking the `openssl` docs, it does not seem provide info on how to include/use a public key to sign the new certificate. – user1506104 Feb 15 '20 at 09:40
  • 2
    @user1506104: I think you need to dig a bit deeper into the documentation. The `-newkey` option you specify explicitly instructs openssl to create a new key. To specify an existing one use the `-key` option. – Steffen Ullrich Feb 15 '20 at 09:47
  • Okay so I read the documentation. You are right, I should use `-key`. So I created a keypair using `openssl genrsa -out keypair.pem 4096`. I used `keypair.pem` as a parameter to the `-key` option. – user1506104 Feb 17 '20 at 13:06
  • I almost had my desired answer until I was trying to extract the public key from my `keypair.pem`. From this https://stackoverflow.com/questions/44474516/how-to-create-public-and-private-key-with-openssl looks like public key and certificate are the same thing? I am not a crypto guy so I am lost. If that is the case, I can use the public key/certificate file and load into my APK and my problem is solved. – user1506104 Feb 17 '20 at 13:27
  • @user1506104: The public key is contained in the certificate but the public key is not the same as the certificate. – Steffen Ullrich Feb 17 '20 at 13:49
  • I just started a bounty for this to get a more Android-specific answer. If you have more info, you may add it now. Thanks. – user1506104 Feb 22 '20 at 17:54