I need to access a REST API by HTTPS from my Xamarin APP. Of course in my development environment, I don't use a publicly signed certificate but signed from my local CA. So I need to add my CA certificate to the trusted CAs on the Android emulator. After some google searches the first approach I've found was, to just drag and drop it into the emulator and then install it with the "Files" app. But this only seems to install it in the user context. Which my App doesn't seem to care about since it still did not accept the certificate from the API as trusted. So I searched for some more...
The next approach was to get the issuer hash value from the certificate, rename the file after it, disable Google APIs
and Google Play Store
and do this:
emulator -avd <avd_name_here> -writable-system
adb root
adb shell remount
adb push <cert_filename> /system/etc/security/cacerts
adb shell "chmod 664 /system/etc/security/cacerts/<cert_filename>"
adb reboot
This did work but has some downsides. Always launch the emulator with -writable-system
which means I have to launch it manually instead of from Visual Studio, and keeping Google APIs
and Google Play Store
disabled. I don't know what difference it makes if I keep those APIs disabled.
I can't really believe that this is the only way to install a CA certificate. How is it done on a real device? I assume I can't just disable the google APIs there?
Tim Biegeleisen's comment made me invest some time looking in the direction of accessing the API in plain text. Neither Android nor iOS do allow this by default. Fortunate enough it is possible to allow it for specific domains which I think is an acceptable solution:
Found here https://devblogs.microsoft.com/xamarin/cleartext-http-android-network-security/
xml\network_security_config.xml
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="true">10.0.2.2</domain> <!-- Debug port -->
<domain includeSubdomains="true">xamarin.com</domain>
</domain-config>
</network-security-config>
Properties\AssemblyInfo.xml
Add android:networkSecurityConfig
to the application header: <manifest>
<application android:networkSecurityConfig="@xml/network_security_config">
...
</application>
</manifest>
Found here: https://stackoverflow.com/a/33306373/3883521
In info.plist
Add Something like this:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>domain.com</key>
<dict>
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<true/>
<key>NSIncludesSubdomains</key>
<true/>
</dict>
</dict>
</dict>
change domain.com
to your domain...