This question already has an answer here:

I want to secure my data transfer using TLS between my own mobile and desktop client applications and my server. I am not at this time interested in web-based applications, so I don't really care that my browser will think my self-signed certificate is dodgy and display a bad message to that effect, because there is no browser to do that in my client applications.

I'd like to self-sign my certificates if possible purely for convenience and cost, although I know certificates aren't really that expensive.

My question is, for mobile and desktop client based applications, are self-signed certificates enough? Are they safe?

marked as duplicate by Steffen Ullrich tls Apr 25 '18 at 16:23

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.


For the safety of the data your key matters. As most people do not know your (public) key certificates are a way that some trusted instance can verify your key and sign a certificate "the key indeed belongs to domain X".

For when you don't need a public CA, it is to costly, or unavailable for other reasons, you have the option to create a self-signed certificate which is signed with the key itself. Users have no direct way to verify it as they do not know the key and have no indication if it is your self-signed certificate or some rogue one.

But there IS a way to trust the certificate and that is validation via another way. Look at the certificate details: There is a fingerprint which can be compared against the fingerprint of the right certificate. If they match, everything is okay.

When you use self-signed certificates just for yourself it is easy to do this verification as you know both sides of the connection. When you are writing an app you can use a hardcoded fingerprint to verify the certificate, which may even be more secure than checking against a CA (because you only need to trust yourself).

What you lose is flexibility. When you want to change the key you need to change the certificate fingerprint in your application. Using the CA system you just let a CA trusted by your application sign the new key and the application will accept it.

To answer your question: They are safe as long as you verify them in some other way which works without a CA. When you disable checking certificates you are way less secure.

  • Thanks. In regards to losing flexibility. Could I not access a server end point via HTTP (not TLS) to obtain the fingerprint from my server, before I open up the TLS connection. Even if the fingerprint data is tampered with, it won't allow my TLS certificate access when I start my HTTPS connection and check against the obtained fingerprint. – Pixel Apr 25 '18 at 9:52
  • 1
    I do not understand what you mean with it won't allow access. You can retrieve a fingerprint over an insecure channel, but then the verification is insecure. Your attack scenario is: A MITM intercepts your connection and presents you a wrong certificate, decrypting your traffic and reencrypting it afterwards to connect the correct site. When you use an insecure channel to get the fingerprint, the MITM gives you the fingerprint of his certificate instead of the original one. So you have no chance to notice what's going on. – allo Apr 25 '18 at 10:03
  • I think I'll go with a CA then. – Pixel Apr 25 '18 at 10:20
  • I've just set up Lets Encrypt which is working nicely. The browser's are happy ! Their certificates last 90 days, which is normal apparently, and they recommend automatically renewing the certificate every 60 days. Seems easy to manually update the certificate in my cPanel. Perhaps I could automate this update every 60 days by setting up a crontab job on my server. Fingers crossed. If so, this will solve all my problems :-D – Pixel Apr 25 '18 at 10:39
  • ... just to follow up on the crontab comment. This is indeed possible according to the Lets Encrypt web site. Just add certbot renew to your list of crontab jobs, e.g. every 60 days or whatever you like. Wow this has totally soved my issue. Free never ending certificates for HTTPS access. Happy days. certbot.eff.org/docs/using.html#renewing-certificates – Pixel Apr 25 '18 at 10:53

TL;DR: They can be safe, if used correctly.

One important thing that even massive companies got horribly wrong is, you actually still need to check self-signed certificate against some list of roots. Anyone can make a self-signed certificate. You need to include yours in your application (hardcode it in), so it can distinguish it from the others (fingerprint should be enough).

Secondly, you probably don't want to use your root certificate directly. Sign another certificate using the root and use that one. Include reasonable expiration (3 months seem ideal). Keep your root offline, ideally in some hardware token. If you need to sign certificates routinely, make an intermediate CA cert, so you can keep the root offline.

You should provide a way to safely revoke your certificates including roots to your application other than app updates. Many users don't update regularly, so make sure you have some independent mechanism to get list of revoked certificates. You should throw security error if you can't verify certificate revocations. Remember you can't rely on your certificates for this, as they may be compromised.

If the root is revoked, you probably want to show a message to the users, saying they need to update.

Not the answer you're looking for? Browse other questions tagged or ask your own question.