Custom CA certificates & Android

With the number of servers I have internally, I have setup my own Certificate Authority and sign all my internal SSL certificates against this private CA.

This offers the useful advantage of being able to import the one CA certificate into all my devices and then being able to validate all connections to remote systems – if you run more than one or two personal servers, I’d highly recommend this approach – certificate signing takes a little bit of getting used to, but it’s a good skill to have.

As I want to access a number of systems via my Android mobile, I needed to import this CA file – the following instructions were followed with ICS release 4.0.3, however it may apply to earlier/later releases as well.

If you’ve followed most typical instructions for building your CA, you will have an PEM encoded CA certificate file in ASCII format. This is fine for import into most browsers and desktop OSes, however Android is particularly fussy with it’s input and requires a binary format only.

You can convert the CA PEM format file with the following command:

openssl x509 -inform PEM -outform DER -in CA.pem -out CA.crt

Then transfer the generated CA.crt file to the sdcard – easiest is via adb:

adb push CA.crt /sdcard/

Once done, you will be able to tell Android to install the CA file via Settings -> Security -> Credential Storage and selecting “Install from storage” and following prompts.

To verify functionality, easiest test is to access an https website signed with your CA certificate via the browser.

Some commenters have had issues - here is me importing a valid CA cert in DER format.

Some commenters have had issues – here is me importing a valid CA cert in DER format.

62 thoughts on “Custom CA certificates & Android

  1. Elmo R.

    I attempt to go to the site (this one with https/8443) and I still get the security warning “this certificate is not from a trusted authority”. How do I import it into a “trusted root”?

    Reply
    1. Jethro Carr Post author

      Websites are a bit different, since at least some of the browsers *glares at firefox mobile* rely on their own internal certificate databases, and not the Android OS DB.

      What browser are you trying to use? I’ve been having “fun” with this recently and it’s not as easy as it should be.

      The Android database should be getting used by most other applications though, such as email, XMPP, wordpress app, etc.

      Reply
  2. Elmo R

    On the android it is the standard browser. I import the CA cert (one that I created years ago and still use for signing everything) into the android. The standard browser still does not accept it for the website that I am visiting whose cert was signed by my CA. If I import the CA cert as a signing cert into ff trusted sig cert, ie trusted sig store or os/x keychain they accept the site as valid if I go to it afterwards. The android browser no-go.

    Reply
    1. Jethro Carr Post author

      Ah, turns out the default browser has it’s own separate credentials DB just to make things difficult. I really wish the browser would just use the Android DB and avoid all this double effort.

      The way I manged to install the cert for the official Android browser was to convert it into DER format first (see the openssl command in the post above for that) and then place the CA.crt file onto a web server my phone could access.

      When you try to load the CA.crt file in the browser, it will allow you to install it by prompting you to name the cert and then install.

      Let me know how that goes for you – I’m going to have to write another blog post explaining how to get the browsers to work, as the Firefox for Android approach is even worse.

      Reply
    2. Jethro Carr Post author

      One thing I’m unsure of is why it worked in the past for me after installing the cert via android’s settings methods.

      Going to conduct some further tests with the browser, something funky is going on.

      Reply
  3. sean

    Hey Jethro, thanks for writing this up. This is so easy with iOS and drives me so batsh!t crazy on Android. Silly question for you: Shouldn’t the imported cert be displayed some where now? I was expecting it to be displayed in
    Security -> Trusted Credentials -> System
    OR
    Security -> Trusted Credentials -> User

    So far I see neither. Maybe I got something wrong?

    Reply
    1. Jethro Carr Post author

      I see my cert appearing in Security -> Trusted Credentials -> User after importing, but maybe they get hidden on different versions of Android? The real test is whether your SSL-using apps are now validating that CA. :-)

      Reply
    2. Jethro Carr Post author

      Oh, if you imported via the browser, maybe it won’t appear in the central DB – did you install from the DER file from the settings window, or by opening the certificate in the browser?

      Reply
      1. sean

        Thanks for your response. Here’s the deal-e-o. I have a self-signed cert (.p12). I exported the public key to a .crt file and tried importing that straight from the file system. The hope was to add it as a trusted CA. After import I jut don’t see it. Should I have exported that as a .pem instead?

        Still bat-sh!t crazy :)

        Thanks man.

        Reply
        1. Jethro Carr Post author

          Actually, I’ve never tried importing a self signed cert, I’ve always been importing CA certs, although there should be little difference as they’re both certificates to be used for validation.

          You could try importing from .p12 and see if that works any better – is Android giving any messages to indicate a successful or failed import?

          Reply
          1. sean

            Thanks for asking. When importing I get a message indicating success, then nothing listed in User certs or Trusted CA’s. I’ve also accidentally tried importing a .p12 that was the whole keypair (whoopsie daisy) and it chewed on it for several minutes (honest!) then did nothing at all.

            But you raise a good point, I’m working for a self-signed cert, not something that you’d use as “hey I’m authoritative! Trust stuff I sign!” I’ll try a more appropriate cert and then I’ll share my results.

            Again, so far your blog has been more useful than just about anything else I’ve seen on the topic, so thanks a bunch.

          2. sean

            working *from, not *for. Sigh. Oh the grammar police are coming to get me, I can hear the sirens wailing now.

      1. Jethro Carr Post author

        Nice one, will be interesting to see what the response to the bug report is.

        Commentators may or may not get emailed replies – depends whether or not they’ve opted in to getting them and whether or not they’ve provided a valid email address.

        Reply
  4. Febs

    Hello dear,

    I added my custom CA certificate to my Android 4.0.4 and the browser goes happily with it.
    Unfortunately though, not a single Ampache client exsisting for Android is caring any bit about my certificate. I suppose there is nothing I can do but waiting for those apps to support the addition of extra CA to the ICS’ database, is that right?

    Thank you very much. :)

    Reply
    1. Jethro Carr Post author

      hi Febs,

      Do you mean that the applications are still refusing to validate the certificate? Or do you mean that they are blindly accepting the certificates?

      I’ve come across some applications which just trust any SSL certificate, regardless what is in the cert store – a prime candidate for man in the middle attack, but other than browsers,most apps which do SSL validation tend to use Android’s DB – so if the CA is visible there, it should be working.

      If you go into Settings / Security / Trusted Credentials and select the User tab, does your imported CA appear there?

      regards,
      jethro

      Reply
  5. TzachyB

    I’ve imported our corporate certificare root CA, intermediate CA, and sub-CA from which the websites’ SSL certificates are issued. all reported installed successfully, the cert file was removed automatically, and appear in the settings->Security->Trusted Credentials->User. All show they are valid and non-expired.

    However, Chrome still unable to validate the identify of SSL sites, even though the certifcate information matches the certificates installed.

    This is on Nexus 7 running 4.1.2. Any ideas?

    Reply
    1. Jethro Carr Post author

      hi TzachyB,

      I’ve had a quick play with Chrome on my Galaxy Nexus 4.1.1, certainly in my case it’s validating my certificates against the ones loaded into Android’s certificate store, so if they’re appearing in the trusted credentials, they should just work.

      Of course technology is never quite that easy… :-(

      Only idea I have at the moment is that your webserver may not be configured to correctly serve up the intermediate certs, I have seen an issue in the past where not serving the intermediate CA from the webserver worked fine with most browsers, but not with a select few. Whilst I’d expect that importing the intermediate and full CAs into the Android cert store would negate this as an issue, it may be that there are some other factors in play here.

      regards,
      Jethro

      Reply
  6. Ramesh

    I am facing problem with my new Galaxy Nexus 10 with Android 4.2.1. I saved the certificate into the Downloads folder of Android Store and then tried installing it. It accepts the password for extracting the certificates. But then it says ‘The certificate is not installed’. I do not know what is wrong and what I should do. I am not getting help from anywhere for past one week.

    Reply
    1. Jethro Carr Post author

      hi Ramesh,

      It sounds like you’re trying to import the wrong sort of a file – a CA certificate will not be password protected, it sounds more like you’re trying to import a key file.

      regards,
      Jethro

      Reply
        1. Jethro Carr Post author

          hi Ramesh,

          A .p12 file typically contains both a certificate and a private key, but I’ve never seen it used to store Certificate Authorities, I suspect you’re trying to import the wrong thing.

          regards,
          Jethro

          Reply
  7. Ramesh

    I am trying to import certificates to access my company application. How and where do I import these certificates in android.

    Reply
    1. Jethro Carr Post author

      Ah, so you’re not actually wanting a CA cert, you’re wanting user authentication certs? Sorry, I don’t know the answer – I would presume it’s the same as the above process for CAs, but if that’s not working for you, then you’ll have to conduct further research.

      Reply
  8. Eridanny Avina

    Hi Jethro!
    Hey I’ve been dealing with this certificates for a long time now, here at the company we use them to authenticate to the wireless network. I installed the certificates, Root CA and Sub CA into my Motorola XT910 but haven’t been able to connect to it.

    I worked with some handhelds using Windows CE or Mobile 5.0/6.0 and it seems that you gotta install the .cer, the .pfx and another format I don’t really remember. I tried to install the pfx into the XT910 but I couldn’t as it does not recognize it.

    Even though I haven’t been able to connect, I can see on the DHCP some mac addresses belonging to iOS or Android devices so it seems that the network allows it but I haven’t figured out how…
    do you have any idea on this?

    Reply
    1. Jethro Carr Post author

      hi Eridanny,

      It sounds like you’re trying to use WiFi 802.1X authentication (http://en.wikipedia.org/wiki/IEEE_802.1X). With 802.1X, your device requires a client-side SSL certificate which is permitted to connect to the network, which is probably your .pfx file that you’ve been unable to import

      I haven’t worked with 802.1X before myself, but my understanding of the specification is that the device can’t request an IP address until the SSL validation has completed successfully, so if you look at the logs of the DHCP server, you shouldn’t see the MAC for your particular device.

      It’s a little old, but try the steps in:
      http://www.omappedia.org/wiki/Configure_Android_Device_to_Test_Enterprise_Security

      Of note, it suggests that the .pfx file needs to be renamed to .p12 in order for Android to detect it as an import-able file, even though both .pfx and .p12 have the same format of contents.

      Hope this helps somewhat, sorry that I don’t have an exact answer for you on this. Let me know how you get on and what the solution ends up being.

      regards,
      Jethro

      Reply
  9. Andrew

    Have you actually followed these directions? Because pretty much everywhere you look, including Android’s own help documents, it says DER format won’t import CA certificates (or private keys), only client certs, which is not what most people are looking for (most people are seeking to avoid self-sign warnings, and that’s what your directions imply).

    To add certification authorities you have to use PKCS#12 format. That leads to other frustrating Android bugs (expecting a password even if one isn’t there, and even at that, the output of OpenSSL seems to not have a valid password no matter what).

    If you have actually gotten apps to use your self-signed web server certs, I’d love to hear about it. Because what you are saying — that you have imported CA certificates by DER — is by all accounts not technically possible in Android.

    Reply
    1. Jethro Carr Post author

      I can’t comment on what the Android documentation says, but this works for me. I even just re-tested in a moment of paranoia that it’s no longer valid on the newer Android versions by deleting and re-importing my keys using the above method. I’ve updated the post with screenshot. :-)

      I have a number of apps that validate the CA correctly (aNag, WordPress and the stock Android browser). Note that additional addon browsers (eg Firefox) may not work, it seems they don’t read the Android certificate store and can’t validate the CA cert.

      Be careful with terminology, these instructions are to import a certification authority. Anything else like self-signed standalone certs, user certs, keys, CA keys (!!) I have no idea about.

      Also note that it’s possible that Android doesn’t accept CAs if generated the “wrong” way. My certs all include the X509v3 extension “X509v3 Basic Constraints: CA:TRUE”, the absence of which has sometimes caused problems in the past with certain systems (glares at Solaris).

      Reply
      1. Jethro Carr Post author

        Actually the stock browser might still have an old cert from previously as I think it has it’s own (hidden) CA store… but the other apps verify it regardless.

        Reply
      2. Andrew

        I’m willing to bet the bit about X509v3 may be my particular issue (which, if so, thanks!), but this, from Google themselves, sure seems to suggest that PKCS#12 is required, and that sentiment seems — if nothing else, implied, by various posts, e.g. on StackOverflow.

        Misleading documentation and subtle bugs seem to be Android’s thing, sometimes.

        Reply
        1. Jethro Carr Post author

          “Android supports DER-encoded X.509 certificates, saved in files with a .crt file extension (if your certificate file has a .cer, .der, or other extension, you must change it to .crt or you won’t be able to install it).”

          So that’s exactly what my instructions do – creates a DER format certificate with a .crt file extension.

          I think the confusion around DER certificates is that they state you can’t import a .der file extension – the file can be in DER format, but must end with .crt. But that’s just their code only looking for certain extensions, the filename has no bearing on the format of the contents.

          Reply
      3. Andrew

        When I would pull my DER format cert in, I got the same dialogs as you but no mention of a CA. Just “package contains: one user cert”. Reading up on line seemed to suggest that this was a result of using the DER format and to get it to be treated as a CA you had to use PKCS#12. PKCS#12 usually expects there to be a private key somewhere in the file, and while you can produce files without such, it usually causes certain software to misbehave. Android will endlessly prompt for the password to the file even if you give the correct password, for instance.

        Reply
        1. Jethro Carr Post author

          I suspect the issue is that your CA certificate is missing some attribute that Android is expecting, such as the X509v3 extension, so it believe it’s a user certificate.

          Note that PKCS#12 files can have two different passwords – the password for the key inside the file and the password for an encrypted PKCS#12 file itself… it may be that Android is asking for one and you’re giving the password for another.

          But PKCS#12 is definitely not the right format for a CA, you would never be importing a private key for a CA. :-)

          Reply
  10. Mike Edenfield

    I had no problem getting my CA root certificate into the Android certificate store and using it to validate web SSL certs. But I cannot find a single email client that seems to pay any attention to the system certs for connecting to a TLS enabled IMAP or SMTP server. I still have to use the option to accept all certificates to get then to connect. Have you actually used your own CA to sign email server certificates and had an Android email client recognize them?

    Reply
    1. Jethro Carr Post author

      I’m actually doing my email unencrypted, since all my connections are secured by a VPN tunnel between my phone and my server anyway – wasn’t much need to set it up.

      I’m using K9 Mail (a fork of the stock mail client with added handy features), if you haven’t tried that already, give it a go – if anything supports it, I would expect K9 to.

      Reply
  11. Elmo R

    Perhaps that’s the difference between what I was seeing. The mail client didn’t accept the CA cert, but the web browser actually did. **Mental Note**

    Reply
  12. Peter Sundstrom

    Been battling with Android and CA certs for a while now.

    As has been previously mentioned, unless your CA vert has x509v3 extensions, Android will treat it as a user cert and NOT a CA cert.

    You can check if your CA cert has x509v3 extensions with:

    openssl x509 -noout -text -in myca.crt

    You should see:

    X509v3 extensions:
    X509v3 Subject Key Identifier:
    6C:47:EE:08:A5:E9:60:E4:2A:A1:0C:10:A1:DE:FD:82:E8:83:2E:A3
    X509v3 Authority Key Identifier:
    keyid:6C:47:EE:08:A5:E9:60:E4:2A:A1:0C:10:A1:DE:FD:82:E8:83:2E:A3

    X509v3 Basic Constraints:
    CA:TRUE

    If not, then you’ll need to regenerate your CA cert.

    If you are using a openssl template, then you need to ensure you have:

    [ v3_ca ]
    subjectKeyIdentifier=hash
    authorityKeyIdentifier=keyid:always,issuer
    basicConstraints=CA:TRUE

    With a reference to them from your req section, eg:

    [req]
    x509_extensions = v3_ca

    Reply
    1. Jethro Carr Post author

      Thanks for posting this detailed set of instructions. :-) The v3_ca thing has caught me out badly in the past, since a lot of systems don’t care, but the few that do cause you hell….

      Reply
  13. Paul Richardson

    Hey Jethro, I fell victim to the “your question isn’t good enough” on StackExchange, but maybe you can help point me in the right direction? Here is my question:

    Suppose you have over a dozen non-Windows radius servers, and you don’t want to pay thousands per year for a signed-cert already trusted by default BYOD OS installs (ex., IOS, Android, Windows).

    So you pay for one cheap SSL signed-cert for an open-auth SSID captive-portal web you setup, authenticate users to AD over this https, and let them download the Radius certs (self-signed root-level) bundled in the appropriate script that installs them.

    Assumptions: Windows has a OS-level cert store, that’s used/connected with IE, but also used for network connections. I presume other OS’s have something similar. I also assume users will click the correct link for their device the first visit to the captive portal, and forever afterwards use the WPA2-Radius (802.1x) SSID

    Is there a better way that’s still cheap? Would the scripts even be helpful, or worsen an already difficult install for mobile devices?

    Reply
    1. Jethro Carr Post author

      hi Paul,

      What are you using or the authentication? EAP-TLS with client certs? Or are you using something that only requires a server cert, such as a EAP-TTLS or UNAUTH-TLS style setup, where clients only have to verify the server’s SSL certificate and don’t need their own client-side certifcates?

      Scripts aren’t going to work for the mobile space, my understanding is that the only option you have for pushing out those certificates would be via the user being manually instructed, unless there’s some group policy/enterprise features with the Active Directory integration or some other method.

      regards,
      Jethro

      Reply
      1. Paul Richardson

        Hi Jethro,

        First, thank you for the answer, which was detailed and VERY helpful. In fact, I think you actually answered my question by clearing up some confusion I had. I kinda-sorta-knew that there were different methods avail. (some where ONLY the server has a cert, and some where both the server and supplicant have certs), but I didn’t know for sure, and didn’t know which one’s fit each of these categories.

        While I’m a little surprised that there is no method to uses scripts to install (or at least help along) the certificates into the OS store for session encryption, I think that the “instructions for manually installing them” would only apply to a minority of devices these days, because I think that most recent versions of IOS, Android, Linux, OSX, and Win 7/8 will automate the process such that the ONLY thing the user actually has to do for the cert install, is hit ‘Yes’ or ‘No’, for trusting the cert (you agree?).

        This was never actually a project I was working on, although I’ve used a self-signed cert in a home lab once, when I setup my own Domain, complete with a Root CA, and Radius VPN (all windows servers). So this time, it was actually a friend of mine, upgrading some radius servers, for a large enterprise, and he wound up getting a really good deal I think (about $700.00 for a WildCard cert, that can be used on all the ISE Radius servers, for 5 years).

        Thanks so much!,
        Paul

        Reply
        1. Jethro Carr Post author

          No worries Paul,

          In regards to automation of the process, I think it will vary depending on their browser, as just downloading the cert with the browser may cause a prompt to install into the browser’s certstore, rather than the OS certstore – but if using the native browser on some platforms (eg IE on Windows), I would expect it to import directly to the OS.

          Guess we’d have to try it out to know for sure. :-)

          regards,
          Jethro

          Reply
          1. Paul Richardson

            A very good point. Big difference if trying to install to the OS from an installed app with it’s own cert store (and there are tons of 3rd party browsers nowadays) —- vice installing as part of the connection process itself (eg., via NIC).

            Thanks again for the insights and help! Much appreciated ;-)

  14. shmic

    I have successfully install .pfx certificate(that contain certs from my CA, root and intermediate, my cer and my private key), but why i cant see it under Trusted credentials/User. I only see certificate from my CA, root and intermediate, but i don’t see my cer. I can only see it if i go to “root/data/misc/keystore/user_0”

    Reply
    1. pedro

      I have the same issue, my certs will work but I don’t see them in the users list therefore I cannot delete one in particular should I wish to do it.
      Any comment to help

      Reply
  15. Andy Davies

    Firstly a very useful blog post thank you, this helped me get our CA into our Android tablets for testing purposes. I can now browse to our web service and get no certificate warnings in ‘Internet’ and ‘Chrome’ browser on our Samsung tablet.

    I still have one issue i’m struggling to resolve in our Android application if I try to access our web service I still get a ‘No peer certificate’ expcetion being fired :(

    I’ve got a Stackoverflow question posted regarding it here: http://stackoverflow.com/questions/19433058/android-ssl-http-request-using-self-signed-cert-and-ca

    Any ideas why I would still get the “No peer certificate” exception even though our CA is installed and happy.

    Thanks,

    Andy

    Reply
    1. Jethro Carr Post author

      I see you’ve solved it now by going with another approach. Based on that error, it almost sounds like your previous approach was trying to setup an SSL connection where it expects a user-side certificate to authenticate with (hence the peer message)…

      Reply
  16. devilbat4202

    I’m configuring Cisco Asa AnyConnect VPN, i have internal CA Server. Asa uses the CA certificate.

    With windows machine users, after trust the CA, i can easily create certificate request file , import and issue it at CA server, and export that certificate to file and import it at the user machine. User can use anyconnect with Cert.

    But with mobile device users (IOS and Android), i don’t know how to create certificate for them.

    Pls help me.

    Reply
    1. Jethro Carr Post author

      Sorry, I have no experience or familiarity with Cisco AnyConnect on mobile devices. In theory the AnyConnect client software should handle all the certs and enrollment in the background for you.

      Reply
  17. dlog2020

    HI Jethro,
    im developing a client which requires client authentication. So I want to create client certificates signed by my self signed CA and put it in the android device. I want to know that this client authentication is possible in android devices? If so can u explain how can I put client certificates in the android device.

    Reply
    1. Jethro Carr Post author

      I believe this is possible, however not having experimented with client certificates on Android myself, I can’t guarantee it. Potentially you may want to do the client authentication within your application anyway, rather than relying on the user to have to install user certs/keys into the Android cert store.

      Reply
  18. sajid

    how to I setup my own certificates using this code openssl x509 -inform PEM -outform DER -in CA.pem -out CA.crt

    Reply
  19. Robert Bowen

    We are using AirWatch to push certs signed by an internal CA so we have a device cert, an intermediate, and a “self-signed” root all on the device. Our app developers are trying to use the device cert for F5 cert-based authentication (using PhoneGap) and they say that they can’t make it work because the chain of trust cannot be verified for self-signed enterprise CA’s. Is there any reason why you would think this would not work for an app? It works fine with the F5 and browser two-factor authentication.

    Reply
    1. Jethro Carr Post author

      Some apps may have their own cert store that ignores the system one.

      Reply
  20. Colin Bell

    We have issues where apps like Facebook, Banking Apps all fail since we have enabled SSL inspection on our firewall. We have the cert install on the device and we can web browse fine to these webpages no problem. Its just the apps themselves which don’t seem to be validating against the user Cert Store.

    Reply
    1. Jethro Carr Post author

      SSL inspection is a horrible, horrible things and these should rightfully fail. The apps are blocking access to their sites since they have detected an untrusted third party (yourself) mangling with content and won’t accept this compromise to their user’s security.

      The only solution is to drop SSL inspection – I look forwards to the day when more apps are like this making SSL inspection untenable in any corporate or government space.

      Reply
      1. Colin Bell

        We really require SSL inspection so it is possible for us to enforce “SafeSearch” when using search engines in our schools. My main problem now is we can create a policy that only does ssl inspection only for search engines but the Google Play app must fall under this category and it fails to work properly.

        Reply

Leave a Reply