leanmind logo leanmind text logo

Posts

AndroidSecurityConfig for local development and useful commands

In one of the projects we have been working on for the last months we’ve been working on both mobile development (native Android) and web development, creating a backend and a front end application. Basically, the mobile app sends messages via POST request to the backend, where they are stored, so they can be displayed in the frontend dashboard we created as well.

Android does not trust unsecure connections (HTTP instead of HTTPS) by default. We were using this kind of connections during the first stages of the project to send these messages, at least until we had a valid certificate, from the Android app to the backend. As a workaround, we enabled HTTP connections temporary the following way:

AndroidManifest.xml

1
2
3
4
5
6
7
8
<?xml version="1.0" encoding="utf-8"?>
<manifest ...>
<application
    ...
    cleartextTrafficPermitted="true"
    ... >
</application>
</manifest>

This simple configuration allowed us to continue working, as we said, until we had a valid certificate in the backend and could use HTTPS. In the meantime we were still able to test the app in our local environment and in the machines that eventually were going to be used for deployment.


Once we had the certificate we redirected our network traffic to HTTPS and thought that was it. Little did we know that it wouldn’t be so easy. We were still not able to access our backend locally.

java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.

Wait… what? What’s a trust anchor? Where should it be? And where are you looking for it?

We were trying to figure out what was happening for a whole week, and we are here to tell you how we managed this issue.

The first thing we did was look it up online, of course, and we came across different workarounds for this, such as enabling ALL connections or adding “patches” to the actual code that eventually will be production code, and we weren’t quite happy with any of those. We kept searching online for other solutions until we found this article deep down the Android developers documentation page.


The solution was generating our own certification authority (CA) to then generate a client certificate too. It would be necessary to add the generated CA to the Android application in order to get Android to accept this CA as a trusted CA. Moreover, we would have to add the keystore (that includes the CA certificate internally) to the backend app. Let’s see it in detail:

Importing this CA in the Android application should be done in a configuration file that must be referenced in the application manifest too.

To do this, we only have to add android:networkSecurityConfig="@xml/network_security_config in the application section of the AndroidManifest.xml. In this case, @xml/network_security_config references a configuration file that must be created inside a xml directory and whose content must be the following:

1
2
3
4
5
6
7
8
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <debug-overrides>
        <trust-anchors>
            <certificates src="@raw/ca" /> <!-- ca certificate with .pem extension -->
        </trust-anchors>
    </debug-overrides>
</network-security-config>

In this way, it is not necessary to install the CA certificate in every device we want to execute the application in, since it is part of the project configuration. It is worth mentioning that this configuration is inside the debug-overrides section, meaining that it is only valid when the application is executed in debug mode. This mode is the default one used by Android studio when we are in the development stage and run our applications.

As it was aforementioned, the backend application must use a keystore that contains the CA certificate and the client certificate previously signed by this CA.

To generate and sign the certificates openssl and keytool tools are needed. The next commands could be used to accomplish this:

1
2
keytool -genkeypair -alias root -dname "cn=Local Development" -validity 10000 -keyalg RSA -keysize 2048 -ext bc:c -keystore root.jks -keypass 123456-storepass 123456
keytool -genkeypair -alias ca -dname "cn=Local Development" -validity 10000 -keyalg RSA -keysize 2048 -ext bc:c -keystore ca.jks -keypass 123456-storepass 123456
1
    keytool -exportcert -rfc -keystore root.jks -alias root -storepass 123456 > root.pem
1
2
3
    keytool -keystore ca.jks -storepass 123456 -certreq -alias ca| keytool -keystore root.jks -storepass 123456 -gencert -alias root -ext bc=0 -ext san=dns:ca -rfc > ca.pem
    keytool -keystore ca.jks -storepass 123456 -importcert -trustcacerts -noprompt -alias root -file root.pem
    keytool -keystore ca.jks -storepass 123456 -importcert -alias ca -file ca.pem
1
2
    keytool -genkeypair -alias server -dname cn=server -validity 10000 -keyalg RSA -keysize 2048 -keystore localDevkeystore.jks -keypass 123456 -storepass 123456
    keytool -keystore localDevkeystore.jks -storepass 123456 -certreq -alias server | keytool -keystore ca.jks -storepass 123456 -gencert -alias ca -ext ku:c=dig,keyEnc -ext "san=ip:10.0.2.2" -ext eku=sa,ca -rfc > server.pem
1
2
3
    keytool -keystore localDevkeystore.jks -storepass 123456 -importcert -trustcacerts -noprompt -alias root -file root.pem
    keytool -keystore localDevkeystore.jks -storepass 123456 -importcert -alias ca -file ca.pem
    keytool -keystore localDevkeystore.jks -storepass 123456 -importcert -alias server -file server.pem

Other useful commands:

1
keytool -importkeystore -srckeystore clientkeystore -srcstoretype JKS -deststoretype PKCS12 -destkeystore keystore.p12
1
openssl pkcs12 -in certificate.p12 -out certificate.pem -clcerts -nokeys
1
openssl pkcs12 -in certificado.p12 -out certificado_key.pem -nocerts -nodes
1
openssl pkcs12 -export -out certificate.pfx -inkey privateKey.key -in certificate.crt
1
keytool -list -v -keystore keystore.jks
Published on 30/07/2021 by
Iván image

Iván Santos González

Mireia image

Mireia Scholz

Do you want more? We invite you to subscribe to our newsletter to get the most relevan articles.

If you enjoy reading our blog, could you imagine how much fun it would be to work with us? let's do it!

We promote the professional growth of your dev team