0

I have an Android app, and I keep getting javax.net.ssl.SSLException: Not trusted server certificate when I try to use it with my own server with my own self-signed certificate.

I am thinking of configuring the Android TrustManager to accept self-signed certificates, or to accept all certificates, so I can debug my app. I've read a bunch of resources on this site about how to do that. Is this safe to do?

Community
  • 1
  • 1
D.W.
  • 3,382
  • 7
  • 44
  • 110

3 Answers3

7

No, this is not safe. It destroys most of the security benefits of SSL/TLS. It leaves your app open to man-in-the-middle attacks. Accepting all self-signed certificates is almost as bad as using no SSL at all.

Do not do this. Do not modify the default policy to accept all certificates, or all self-signed certificates, or disable the hostname verification checks.

What to do instead

There are a few candidate alternatives that are reasonable.

One reasonable option is to introduce a configuration option for developer debugging. If this option is enabled, you can disable the certificate verification; if it is disabled, you use the standard certificate verification checks. The default should be for it to be disabled. Also, make sure that the option can only be enabled on devices that have developer settings enabled and that are registered with a Google developer account, to prevent a normal user from inadvertently destroying their own security.

Alternatively, another reasonable option is to add your own self-signed certificate to the certificate store, so that it will be trusted. Android makes this a bit more painful than necessary; what you'll need to do is implement your own custom TrustManager that references a custom TrustStore. The custom TrustStore will include your self-signed cert. The custom TrustManager will accept the certificate if it matches that one self-signed cert, or if it passes all the regular certificate verification checks. You can find details on how to do that on this blog post and this tutorial.

Either of these will let you test and debug locally, and ensure you are running the same code in test and in production. It will also avoid the risk of insecure test code leaking into production and compromising the security of your users.

Can I get even better security?

If your app is written to connect to a single specific server, you can optionally get even better security by using certificate pinning. This basically means you'll only accept certificates that are signed by a single chosen certificate authority (CA), not one signed by any of the dozens of CAs that Android trusts. You can find details on how to do that at this tutorial, or using Moxie Marlinspike's library (read his introduction here), or this blog post.

However, this is arguably secondary. The most important thing is to avoid disabling the standard certificate validation checks by accepting all certs (or all self-signed certs).

Is it really a big deal?

Does it really matter? Yeah, it probably does.

Research studies have found that many apps have a serious security vulnerability, due to disabling some or all certification validation checks -- perhaps 15% of apps are affected. In many situations where an attacker might be able to eavesdrop on the SSL traffic, they can also mount a man-in-the-middle attack: for instance, if one of the users of your app is connecting via an open Wifi network, then anyone in range can mount a man-in-the-middle attack on that user (not just eavesdrop). It's worth avoiding this vulnerability.

Citation:

D.W.
  • 3,382
  • 7
  • 44
  • 110
  • FWIW, [my CWAC-Security library](https://github.com/commonsguy/cwac-security/) offers [a `TrustManagerBuilder`](https://github.com/commonsguy/cwac-security/blob/master/TrustManagerBuilder.markdown) that helps simplify the coding around creating a custom `TrustManager` – CommonsWare May 29 '14 at 00:21
1

You can ask the TrustManager to accept your own self-signed certificate. Here there are 2 methods returning respectively a DefaultHttpClientand a HttpsURLConnection, accepting as parameters also the self-signed certificate. You can copy and past the code or adapt the part of the TrustManager.

Community
  • 1
  • 1
bardi
  • 373
  • 5
  • 17
0

If you think of not using the default trust manager you should probably read before http://www.theregister.co.uk/2012/10/21/android_app_ssl_vulnerability/. Just to quote:

...found that 17 percent of the SSL-using apps in their sample suffered from implementations that potentially made them vulnerable to man-in-the-middle MITM attacks.

Steffen Ullrich
  • 114,247
  • 10
  • 131
  • 172