What is the best approach to avoid expiring root certificates in IoT devices? - ssl-certificate

I have esp32-based devices in the field which are connecting to a back-end server that I fully control.
These devices include a default root certificate bundle
I am worried that one day, all these certificates will expire.
I want to avoid this problem for any future devices that I will deploy into the field.
What is the best long-term solution for the "expiring root certificate" problem?
I have the option for OTA updates, but I would rather find an approach that does not require me to update the devices once they are in the field.
PS: Maybe this is relevant: I will soon be migrating my back end from Heroku to AWS.

Theoretically, you could implement what a web browser does. There is a list of trusted authorities that sign certificates.
The easiest and cheapest way is to use LetsEncrypt, even though their service is oriented for https certificates, you could sign your own certificate. After you sign the certificate it is only a matter of going to their site to download the latest root certificate from your embedded device.

Related

Self signed certificate or CA certificate for IoT device

I can't understand which is the real benefit of using a CA certificate when it comes to secure communications between servers and IoT devices.
I'm working at an IoT device that uses Ubuntu as OS and I was planning to use CA certificate. But what happen if my users are not updating their devices firmware?
now that certificates expires after 1 year and considering that some users are not updating their IoT devices for a long time... the risk I'll run into is that those devices could not be updated after the cert expires since they can't communicate with my servers.
With a self signed cert I can set an expiration of 45 years and anyway I'll be to authority and I can revoke or decide when it is time to release a new cert or even cross signing certificate.
I'm obviously talking only about the communication between the device and servers... the rest api for users will use a default CA cert.
Another option that I'm considering is to use a CA cert for device and servers communication but also adding a self signed certificate that I can use as backup in case the the main certificate expires and the device needs to download new software (that will contain the new certificate) is this a viable solution?
Should I handle certificates in this way?! or maybe should I just use the OS root store and ensure that it is updated somehow? (in this case ... how?... the only way is to release an update of the device firmare I suppose)
Certificates are used for authentication and encryption. See https://www.ssl.com/faqs/what-is-a-certificate-authority/
If you want to make sure that, data you are receiving is coming from authenticated devices then you will use certificates.
You can use certificates to encrypt each and every request. But it will be heavy on resources. Or you use certificates to for authentication and return an JWT token for further request. (This is how service account works in cloud.)
Manual certificate management will become complicated in no time.
Service account is a common way to authenticate apps/ devices. Keycloak is an open source option to support service accounts.
You should keep device updation separate from authentication. Device updation may or may not happen on authenticated device. And waiting for certificate expiration to update the device sounds strange.

How to make sure Certificate is safe in WCF

WCF supports to use certificate to authenticate Client. If a malicious user steals client's certificate and creates connection with Server. Can Server know this? If we install certificate to Microsoft Certificate Store, how to make sure it is safe? I could easily read the certificate in store by code.
Can Server know this?
no.
If we install certificate to Microsoft Certificate Store, how to make sure it is safe?
you can't.
Certificates themselves don't solve secret leaking problem. They provide better security on a transport, better UX when authenticating on remote server, but they can leak as easy as passwords (ok, not that easy, but can). Such issues are solved using different techniques, like storing the certificate on a smart card where you need to have both, a card itself and PIN/Password to access the card. These are out-of-band solutions the certificate is not aware about, thus you can't tell whether the key is secure or not.

Is it possible to use or negotiate different SSL certificates based on client's browser

I am using let's encrypt now, and I am planning on using my own CA from now on. The usage is for personal media server and cloud storage.
Now I can install the root CA on the devices I own, but occasionally I get visitors when I share stuff. I provided the certificates to install for the visitors and not all of them do that.
My question is, is it possible to use my rootCA signed certificate if it is installed on client system/browser, or else to fallback and use let's encrypt.
Let's encrypt is good enough, but re-issuing every 3 months and verifiying domains is a pain, especially when there is no wild-card.
No. The ClientHello message doesn't include any information about recognized CAs.

SSL Pinning and certificate expiry

This question relates to the use of SSL Pinning in a client app against a web api and certificate
expiry.
Scenario:
I own example.com and have a subdomain where an api is hosted, as such: api.example.com
I wish to use the api over SSL, so an SSL Certificate is created for the subdomain.
After the certificate has been acquired, I have:
A Public Certificate
A Intermediate Certificate
A Private Key
It's my understanding that I install these certificates on my webserver.
I then wish for my client app to connect to the api. To mitigate against man-in-the-middle style
attacks, I wish to use SSL Pinning, so that the client will only communicate with my api, not
someone spoofing it.
In order to pin in the client app, I have two choices, either pin against the public or intermediate
certificate.
Let's say I implement this.
What happens when the certificate on api.example.com expires?
It's my understanding that the client app would no longer work.
Do I need to regenerate a complete set of public/intermediate/private items again? and then
put a new public or intermediate certificate in the app?
Question:
I would still like the client app to work until the certificate on api.example.com was updated.
Of course, a new certificate can be put in the client app, but things like roll-out take time.
How can I handle this?
I've read that Google updates their certificate every month, but somehow manages to keep the public key the same: How to pin the Public key of a certificate on iOS
If that's possible, then the solution is to simply extract the public key from the server and check it against the locally stored public key...but how do Google do it?
Thanks
Chris
Note: I'm more familiar with browser to server pinning (HTTP Public Key Pinning - HPKP) rather than app to server pinning, but I presume the principal is the same. In HPKP the pinning policy is provided by the server as a HTTP header but understand this is often built into the app rather than read from the HTTP response. So read below answer with all that in mind:
Pinning is usually against the key not the cert and can be a multiple levels. So you've several choices:
Reuse the same key/crt to generate a new cert. Some (rightly in my opinion!) recommend generating a new key each time you renew your cert but this is complicated when you use pinning. So does pinning encourage poor security habits like key reuse?
Have several back up keys in your pinning policy and rotate them around on cert renewal discarding your oldest and adding a new one with plenty of time and updates to never be caught short. Personally I prefer to generate the key at cert renewal time rather than have some backups around which may or may have been compromised so I'm not a particular fan of this either. And how many backups should you have? E.g. If you need to reissue a cert because of compromise around renewal and also mess it up? So 2? 3? 100?
Pin further up. Say the first intermediate or the root CA cert. So any newly issued cert is still trusted (providing it's issued by same cert path) The downside of this is four fold: i) You still leave yourself open to miss-issued certs issued by that pinned cert (not a massive deal IMHO as you've still massively reduced your attack surface but still a concern to some people), ii) you cannot guarantee the client will use that intermediate cert as there are sometimes multiple valid paths. This second one is a much bigger deal. You'd think that providing the intermediate cert would guarantee this would be used but that's not the case (plenty of sha-1 examples of this). iii) There's no guarantee new cert will be issued by same intermediate or root (especially when technologies change like introduction of sha2), so to me this whole option is a non-starter iv) It ties you in to using same cert provider (perhaps not a big deal but I like the freedom to move). Not sure if apps support this feature natively anyway but browsers certainly do.
Renew in advance and do not use the new key until policy cache expires. For example if you have one year certs and a 30 day pinning policy then you can renew after 11 months, add the new key to the policy, then wait 30 days so you can be sure everyone will have picked up new policy or at least the old policy will have expired, then switch keys and certs. Depends on a short policy and potentially wastes a portion of that though (at least 30 days in this example), unless cert provider provides cert in advance starting on day after old policy expires. For an app, if pinning policy is hard coded into it, then this might involve the length of time it takes to push out an update.
Ultimately, because certs do require renewing, I'm not a big fan of pinning. I don't think making something that is subject to periodic renewal, semi-permanent is the right answer. And there are even some talk of pre-loading pinning policies in browsers which just makes me shudder.
Pinning provides assurance that a rogue CA is not issuing certs for your domain but how likely is that really compared to the hassle of pinning? Something like Certificate Transparency - or even report only pinning may be a better answer to that problem even if they don't actually stop that attack.
Finally locally installed roots (e.g. for antivirus scanners or corporate proxies), bypass pinning checks (on the browser at least) which again reduces its effectiveness in my eyes.
So think carefully before using pinning and make sure you understand all the consequences.
The mozilla developer site recommends to pin the certificate of the intermediate CA that signed the server certificate.
"it is recommended to place the pin on the intermediate certificate of the CA that issued the server certificate, to ease certificates renewals and rotations."
For more information on implementing and testing public key pinning you can refer Implementing and Testing HTTP Public Key Pinning (HPKP)
Your application can store multiple certificates in its pin list. The procedure for changing the cert would then be:
Some time before the certificate expires, release a new version of your app with a replacement cert in the pin list, as well as the original cert
when the old certificate expires, replace it on the server - the app should then still work as the new cert will already be in the pin list
Some time after the cert expires, release a new version of your app removing the old cert
Remember your users have to update the app before the old cert expires

Does enabling SSL require more than just turning it on?

I run an nginx-powered application and I recently turned my attention to using it over https. This is the module in nginx that does this: http://wiki.nginx.org/HttpSslModule
However, I'm somewhat unclear about what is actually required to run a site over https.
What else is there to do to serve my site over ssl? What is the role of the certificate, and is it a requirement that I purchase it from somewhere?
You need a certificate to prove to your user that the server they're connected to is indeed the one intended (and not a MITM attacker).
If your server is to be used by a limited number of users to whom you could give a certificate explicitly, you could use a self-signed certificate or create your own certification authority (CA).
Otherwise, if you want your certificate to be recognised by most browsers, you'll need to get one from a commercial CA.
You should find more details in this answer. You may also be interested in this.