I have an app that has a site certificate hash pinned with OkHttp3 similar to the method mentioned here
The site certificate is about to expire soon though and I realized that I need to be able to support a new site certificate as soon as I switch update that on the site, as well as let the current one still work until then. Is there a way to pin 2 certificates for the same site so that both are supported seamlessly (i.e when the current one expires and one is no longer valid as well as the new one as soon it is updated)?
TIA
This is the documented behaviour of CertificatePinner. So just add pins for your current and old certificate.
http://square.github.io/okhttp/3.x/okhttp/okhttp3/CertificatePinner.html#check-java.lang.String-java.util.List-
Confirms that at least one of the certificates pinned for hostname is
in peerCertificates. Does nothing if there are no certificates pinned
for hostname. OkHttp calls this after a successful TLS handshake, but
before the connection is used.
n.b. Because of the expiry of your certificates may happen before old clients update, it is usually advised to also pin against the CA you use also which is quite likely to be consistent across old and new certificates. This will ensure even if your current and next certificate expire or are revoked, you would be able to authenticate with a new certificate generated and older clients.
https://community.letsencrypt.org/t/hpkp-best-practices-if-you-choose-to-implement/4625
Related
i need to implement security measure for my android app which currently runs with http
I was reading on the ssl and found that we need root and intermediate certificates,
if i am not purchasing the certificate from outside how can i get the root and intermediate certificates ..
thanks
Do you mean you will be using a self signed or self issued certificate on the public facing server? (Neither of which I would recommend)
If you really want to try and do that then:
a self signed certificate sign's itself (it is its own CA)
a self issued certificate on windows for example use the mmc certificates tool, you can download the public part of any certificates in the trust chain (but then you'd need to get them on to a device for them to be useful and something owners of the devices would not like since I would bet you do not have proper key management in place).
A potentially better way would be to use a properly issued certificate for your production site which would allow you to validate the hostname and trust chain correctly.
But for your local dev builds have it ignore these two checks (I would also have it put up a Toast if it was running in this mode so you don't issue this by mistake).
It feels like I searched the whole web already, but all I found are hints on how to accept an invalid or self-signed certificate automatically. (Using custom HttpClient and SSLSocketFactory - I already got that working.)
But what I want for my app is that the user gets a browser-like dialog asking something like "Do you really want to trust this server? Here, have a look at its certificate." (But only if the certificate isn't trusted by the default checks.)
Then the certificate should be put in the app's certificate store, so next time it's accepted automatically.
So what I need to know is:
How to download the certificate (chain) for a specific host/port combination (to be able to show it to the user)?
How to store the certificate in a way so I can load it in a KeyStore later?
This is my planned work flow in the app:
Send a request to the server with my custom HttpClient. Maybe the certificate is trusted by the system or already in my store (if yes, go to 4).
If the request failed due to SSL issues, show the user the certificate and ask whether to trust this connection.
If the user chose to trust, store the certificate in my store and go to 1.
Hooray, connection is ready to use.
So anyone knows how to do this?
Don't disable CA checks and catch the exception when trying to connect to a non CA certificate. When you catch the exception, launch your page for the user to accept/decline. If he accepts, then launch a new connection with CA checks disabled.
Our Android application is interfacing with a server than employs a certificate chain, with certificates issued by Verisign. We were able to establish SSL sessions with this endpoint so far. This Verisign certificate is due to expire next month.
Questions:
1. Should Server site get a new certificate reissued from Verisign and everything would just work?
2. Can the original certificate expiration date be just extended rather than issue a new one?
What can be done to ensure a smooth transition?
You need to be issued a new certificate, but it needn't be issued by Verisign. Any trusted authority can sign the certificate.
The key store containing trusted issuers is here:
/system/etc/security/cacerts.bks
You cannot extend a certificate, but you shouldn't need to. As long as the server certificate is issued by a CA you trust (does not to be VeriSign), things should continue to work. You might want to replace the cert sooner rather than later though, because people might have clocks that are off by a few days.
I have a website with a number of RESTful web services that are used by an Android app. I want to let all requests go through HTTPS. Hence, I need an SSL certificate for my website.
Q: Do I need to buy an SSL certificate or can I use a self-signed certificate in this case? (I don't want to waste money on something I don't need.)
I can think of these approaches:
Buy an SSL certificate with Extended Validation (green address
bar). Probably not necessary.
Buy an SSL certificate without Extended Validation. This should suffice, no?
Self-sign an SSL certificate. Not sure what this implies?
If your biggest concern is not spending money http://www.startssl.com/ provides free basic SSL certificates for a year so that may be worth looking into. I do not know off-hand which CAs are trusted by default in Android so it may turn out to be effectively the same as a self-signed certificate from the app's perspective.
Using a self-signed certificate would require finding a way to make sure the Android app expected that self-signed certificate and trusted not only your initial certificate but any replacement certificates in the future. I suspect this is more trouble than it is worth although I do not know much about Android development or the app in question so I may be overestimating the difficulty involved.
An EV certificate does provide a stronger guarantee to the client that the service is actually your service and owned by you but it does incur additional costs. Choosing an EV versus DV certificate becomes more of a risk/reward judgement call. Annecdotally, I typically only see EV certificates on financial sites and others where you would typically expect to find a high bar for security.
I want to perform extra validation for SSL connections I make in an android app.
Basically I need to be able to:
See if the certificate of the remote host I am connected to has Extended Validation (EV) status
Find out the root certificate authority for the certificate of the remote end. E.g. I want to know if it is a VeriSign certificate or not.
To elaborate a bit more, I am writing a client that needs a high level of security and our organization is using EV certificates from VeriSign on all servers. I want to prevent any compromised certificate authority, or anyone that can fool a certificate authority to forge a certificate for our domain be able to hijack the application.
Is this doable and if so, how? Is there a way to get more information about the certificate of the remote end from a URLConnection object or a HTTPClient object and so on?
First: you can't possibly 'prevent any compromised certificate authority' from issuing a certificate for your domain. If it is compromised, they can issue whatever they want. What you can do is create a trust store with a limited number of trusted CA certificates, say, VeriSign only. That way, even if an related CA is compromised and issues a cert for your domain, it wouldn't matter since you don't trust it in the first place. That would also take care of second bullet. To have additional checks you need to implement and install your own X509TrustManager. Check the JSSE reference guide for details.