As per Android N documentation -
By default, apps that target Android N only trust system-provided certificates and no longer trust user-added Certificate Authorities (CA). Apps targeting Android N that wish to trust user-added CAs should use the Network Security Config to specify how user CAs should be trusted.
What I understood from the doc is that user installed certificates will no longer be trusted from Android N. So there should be a way to make it trust. Doc says you can specify the network sec config in manifest file like -
<?xml version="1.0" encoding="utf-8"?>
<manifest ... >
<application android:networkSecurityConfig="#xml/network_security_config"
... >
...
</application>
</manifest>
And then specify the network config -
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<domain-config>
<domain includeSubdomains="true">example.com</domain>
<trust-anchors>
<certificates src="#raw/my_ca"/>
</trust-anchors>
</domain-config>
</network-security-config>
But this is obviously static data. I am interested to know if there is a way to add certificates in trust store dynamically as in real scenarios will have dynamic certs and expiry scenarios. Docs did not clear these for me.
Q1. Any thought or suggestions on how to achieve dynamic addition of trusted certs?
Q2. Does this also affect other certs like wifi certs which may not be app specific? How to trust a custom wifi cert then? How to add it it native trust store?
Related
I want to pin a self-signed certificate.
According to the Android Developer Guide Pin certificates I assume the following configuration should work:
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<domain-config>
<domain includeSubdomains="true">192.168.0.199</domain>
<pin-set expiration="2022-10-22">
<pin digest="SHA-256">SZBI91U8Y1j4toZoG5cTRbzl7Nr+aeTb3a8IWy9LKy0=</pin>
</pin-set>
</domain-config>
</network-security-config>
However, I only get the following error:
java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
I thought the point of pinning the certificate explicitly was to avoid the need for a trust anchor.
When I add the self-signed cert as trust anchor: Add the certificate file as Resources/raw/server.cert for the Android project (same as network-security-config.xml) and change network-security-config.xml to:
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<domain-config>
<domain includeSubdomains="true">192.168.0.199</domain>
<trust-anchors>
<certificates src="system" />
<certificates src="#raw/server" />
</trust-anchors>
<pin-set expiration="2022-10-22">
<pin digest="SHA-256">SZBI91U8Y1j4toZoG5cTRbzl7Nr+aeTb3a8IWy9LKy0=</pin>
</pin-set>
</domain-config>
</network-security-config>
I get the error:
Hostname 192.168.0.199 not verified:
certificate: sha1/pRy8qhJSgP6btrNTqGNFxO8Yd9g=
DN: CN=192.168.0.199,O=myorg,ST=Some-State,C=DE\
subjectAltNames: []
The hostname is the CN in the certificate and I got the SHA256 pin value from gnutls-cli.
Questions
What's wrong with my configuration? How can I pin the certificate?
Is there another way to get the SHA256 pin value for a certificate?
Do I need to add the cert file as trust anchor?
Is there an alternative way to pin the certificate?
Is the IP allowed as hostname? If not how to pin certificates for IPs?
thanks in advance
Update 2021-11-08
I found a partial solution: Since my certificate was created for an IP address instead of a host name, the IP address must be in the subject alt name field of the certificate. Then the certificate needs to be added as trust-achor in the base-config.
What I still don't understand is why I need to add the certifcate instead of the pin.
Starting from Android API level 24 it is possible to define a Network Security Configuration and reference it from the Android Manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest ... >
<application android:networkSecurityConfig="#xml/network_security_config"
... >
...
</application>
</manifest>
Source: https://developer.android.com/training/articles/security-config.html#manifest (accessed 2021-08-10)
I have a use case where a number of CA certificates are included in an Android library that I am using. I would like to restrict my security configuration to these certificates using trust-anchors.
The network security configuration allows this:
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<domain-config>
<domain includeSubdomains="true">example.com</domain>
<trust-anchors>
<certificates src="#raw/my_ca"/>
</trust-anchors>
</domain-config>
</network-security-config>
Source: https://developer.android.com/training/articles/security-config.html#ConfigCustom (accessed 2021-08-10)
But the certificates are located in my Android library and I don't want to duplicate the files.
How can I reference the library CA certificates from my apps network security configuration?
CA certificates should be put in the res/raw folder, not in the assets folder, in the library project.
This way it is possible to reference the certificates from the app using the library through the network security configuration.
At least everything compiles now. Although, I have not yet verified a fully working setup due to a different issue, see: Combine Network Security Configuration with OkHttp and custom CAs
I am trying to do a debug session on an App (Android) by monitoring the outbound/inbound HTTP traffic on Andy emulator.For SSL traffic I get following error :
Failure: SSLHandshake: Unsupported curveId: 29
In the past I was not receiving above error using that app .Could you guys tell me what this error means and how to fix it?Is there any problem within the app that causes to receive SSL error? Thanks
See the Android section in their documentation https://www.charlesproxy.com/documentation/using-charles/ssl-certificates
You need to add a network security config file for Android N and higher devices.
From Android N+, we have to add the Certificate in your app in network_security_config.xml and manifest.xml in order to intercept the HTTPS Traffic.
network_security_config.xml
<network-security-config>
<debug-overrides>
<trust-anchors>
<!-- Trust user added CAs while debuggable only -->
<certificates src="user" />
</trust-anchors>
</debug-overrides>
</network-security-config>
manifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest ... >
<application android:networkSecurityConfig="#xml/network_security_config" ... >
...
</application>
</manifest>
Here is the quick tutorial: https://docs.proxyman.io/debug-devices/android-device
I have a live working restful API returning JSON data created with nodeJS and uploaded to a webServer. Also I'm using react native to build the front end for both android and IOS. The api works fine and returns data as expected when I build debug version of the app in android using 'react-native run-android'. But the app seems to be unable to fetch data from the API while I build the release version in android using 'cd android && ./gradlew assembleRelease'. I can't see any hits in the node server from my app.
I'm using axios for my http requests.
My problem is resolved. As of Google's official documentation, requests to a web Server is possible only with a secured domain with valid SSL certificate.To force HTTP requests from insecure domain or domain with self signed certificate, just add a file in
"yourProject/android/app/src/main/res/xml/network_security_config.xml"
with following contents-
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<domain-config cleartextTrafficPermitted="true">
<!-- For React Native Hot-reloading system -->
<!-- If you are running on a device insert your computer IP -->
<domain includeSubdomains="true">localhost</domain>
<domain includeSubdomains="true">your own domain ip</domain>
<trust-anchors>
<certificates src="system" />
<certificates src="user" />
</trust-anchors>
</domain-config>
<base-config cleartextTrafficPermitted="false" />
</network-security-config>
and then import the xml file by adding this line to AndroidManifest.xml between application tag-
<application...
android:networkSecurityConfig="#xml/network_security_config"
...>
Adding android:usesCleartextTraffic="true" in android/app/src/main/AndroidManifest.xml works well for me. We may want to add also in the debug folder (sibling of main) for development purpose.
So I have been trying to get requests/SSL through burp using my phone. basically I followed these steps very carefully many times:
Configuring your Browser to work with Burp
Configuring an Android Device to Work With Burp
I used different ports such as 8888, 8082, 8080 and I also of course change the port in the wi-fi that I use with the computers IP etc 192.168.10.190 - First of all it says on my phone that it couldn't find any network but when I access etc Google, Youtube it works fine. What I then need to do is to get a certification so I can use it as trusted certfication/device
so I followed this one:
Installing Burp's CA Certificate in an Android Device
So whenever I try to access http://burp to get certification it says ERR_NAME_NOT_RESOLVED/No response received from remote server - I tried using http://localhost:8080/ but same issue.
What can I do to make it work so I can see all the requests/SSL through Burp Suite?
To chris:
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config>
<trust-anchors>
<certificates src="system" />
<certificates src="user" />
</trust-anchors>
</base-config>
<debug-overrides>
<trust-anchors>
<certificates src="user" />
</trust-anchors>
</debug-overrides>
</network-security-config>
I found a little trick to use the Burp certificate on Android from 4.2 and up.
Requisite: Install Firefox
Listen on all interfaces
Access from you Computer http://127.0.0.1:8080 and download "cert.der" clicking on "CA Certificate" link on Top Right corner
Open "Firefox", go to Options / Privacy and Security / Certificates.
Open "See certificates" dialog, go to "Authorities", click "Import" and choose the saved "cert.der" file.
Scroll down to PortSwigger Auth, select "PortSwigger CA" and click Export.
Save this file as "PortSwiggerCA.crt"
Upload this file to your Android Phone
Go To Settings
Type on search box: "Install from Storage"
Select the "PortSwiggerCA.crt" file
Choose "Apps" not "WI-FI"
Go to your Wireless Advanced Settings, use Manual Proxy and point to your Machine local network address.
Ex.: 192.168.1.200 port 8080
Voilá
Obs.: This will not work with Certificate Pinned APK's like Whatsapp
and Facebook. You need to tweak them.
The guide seems to be missing instructions regarding networkSecurityConfig which was added in API 24. https://developer.android.com/training/articles/security-config
To enable this in debug mode you could add a network_security_config into res/xml
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<debug-overrides>
<trust-anchors>
<!-- Trust user added CAs while debuggable only -->
<certificates src="user" />
</trust-anchors>
</debug-overrides>
</network-security-config>
And then reference this in your manifest by referencing the config file
<application
android:networkSecurityConfig="#xml/network_security_config"
tools:targetApi="24"