2

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?

Shalu T D
  • 3,921
  • 2
  • 26
  • 37
Marco Rebsamen
  • 605
  • 7
  • 30
  • My advice to you is to avoid messing around with self signed certificates, because it can be a real headache. Just build your app using `HTTP`, and then we you are finally ready to deploy, turn on SSL, and use a CA from a known authority. The JVM should already ship with a cert for that CA in its truststore, and you should not have to do any configuration work at all. – Tim Biegeleisen Jun 22 '20 at 07:09
  • Seems actually to be the easiest way – Marco Rebsamen Jun 22 '20 at 11:04
  • I can confirm it's definitely a headache with self signed certificates. Couldn't make it working at all on both plattforms and switched to `HTTP` as well. It's really disappointing. – pschlz Dec 22 '20 at 17:47

1 Answers1

3

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:

Android

Found here https://devblogs.microsoft.com/xamarin/cleartext-http-android-network-security/

  1. Add the following file and folder under resources in the Android project: xml\network_security_config.xml
  2. Add lines like this to the file:
    <?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>
  1. In Properties\AssemblyInfo.xml Add android:networkSecurityConfig to the application header:
    <manifest>
    <application android:networkSecurityConfig="@xml/network_security_config">
        ...
    </application>
    </manifest>

iOS

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...

Marco Rebsamen
  • 605
  • 7
  • 30