I can't find good information regarding certificate pinning in iOS and Amazon Certificate Manager.
They recommend you don't pin against an ACM certificate.
https://docs.aws.amazon.com/acm/latest/userguide/acm-bestpractices.html#best-practices-pinning
We recommend that your application not pin an ACM Certificate
The reason they don't recommend it is that:
To renew a certificate, ACM generates a new public-private key pair.
Instead, they recommend:
If you're using a public certificate, pin your application to all available Amazon root certificates.
I understand why not to pin to an ACM Certificate - because you will have to release updates with new certificates risking possible bricking of clients. You also can't pin against the public key because it will change.
What I don't understand is how pinning against only the root certificates is ok? Will it still prevent man in the middle attacks? How is this more secure?
Can someone explain it better?
It would not be more secured to pin against the root certificate. I think what the Amazon documentation trying to recommend is a way that would not break your network connection in the case that when the certificate expires and renews.
Here's the quote from this website explaining the different kinds of certificate pinning:
https://carvesystems.com/news/cert_pin/
Leaf Cert: A leaf cert is the top level cert in a certificate chain.
Pinning a leaf certs brings us to almost complete certainty that the
certificate matches. However, if you cycle your leaf certs often,
updates need to roll out fairly frequently to make sure your
customer’s app continues to work.
Intermediate Cert: The intermediate cert lives between the leaf and
root cert. In this case, pinning against the intermediate cert, you’re
putting your trust in the intermediate certificate authority.
Therefore, you can update your server’s leaf cert more often, as the
validation of certs occurs on the intermediate cert.
Root Cert: Finally, the root cert comes from the trusted certificate
authority. Pinning the root cert alone puts trust in the root cert
authority, as well as all intermediaries that the root cert authority
trusts.
Hope this helps
Related
I am looking at a clear answer on to how to renew the CA successfully in EJBCA. We have thousands of client certificates already issued by the EJBCA which is actually working as a subCA signed by an external CA. The process is indeed documented here https://www.ejbca.org/docs/Renewing_a_SubCA_Signed_by_an_External_CA.html but it does not state clearly, what will happen to the already issued client certificates. Will they continue to be successfully validated via the new CA?
That link give two options for renewing the key:
1. Using the same CA signing key
If you refer to RFC 3647, this is the correct definition of a renewal. In this case, the keys remain the same and the certificate Subject remains the same. Effectively, the new certificate is the same as the old albeit with different dates.
Relying parties will trust this certificate in the same way as they trusted the original.
2. Generating new CA signing keys
The correct term for this is a re-key. The key changes and the Subject stays the same. The certificate is a different certificate as far as any relying parties are concerned. This may mean more work for you.
You'll first need to ascertain what will happen to the original CA certificate. Will it expire or be revoked, or will it still be valid?
If it's being retired, you'll need to replace all certificates issued by that original CA certificate as they will only verify through the original CA.
If not, and you're re-keying for other reasons, for example the original CA certificate's CRL has become too large to manage, then there is no need to rush into replacing all your subscriber certificates. The old CA certificate will still verify those certificates, while subscriber certificates issued by the new CA certificate will be verified by the new CA certificate.
I'm currently implementing the TrustKit framework in my iOS app to enable SPKI pinning for SSL connections.
I'm stumbling upon the "backup pin" which is mandatory for a correct TrustKit configuration. Unfortunately the API documentation only states that a backup pin is needed but it doesn't tell me what it should be. The chain of trust looks like this:
GeoTrust Global CA
| GeoTrust SSL CA - G3
| myServer.com
So I pin the SPKI hash for myServer.com-certificate as the primary pin. What is my backup pin?
Unfortunately I didn't find a lot of information about this topic. One of the few resources I found is this article by Hubert Le Van Gong from PayPal. He says about backup pins:
"Whatever the number of pin values, a backup pin is an absolute must-have. Note that the existence of a backup pin is a mandate in HPKP (i.e. for the web case) but it is equally important in the mobile app space. In both cases, the key pair corresponding to the backup pin should be kept offline until an issue arises with the primary pin/key."
I especially don't get the part with "should be kept offline".
About the question what to pin:
Root CA certificate are probably best. Therefore, when pinning to multiple values (e.g. 2), intermediate CA – root CA is a sound approach in my opinion. That said, it is also perfectly OK to only pin to a single certificate as long as that certificate is a root CA.
From this I understand my backup pin could be the root CA (it's SPKI hash to be exact). However I wonder how an intermediate or even root CA can be good pins. From my understanding this would validate the pinning for every certificate that has this intermediate/root CA in it's chain.
What am I getting wrong here?
I wonder how an intermediate or even root CA can be good pins. From my understanding this would validate the pinning for every certificate that has this intermediate/root CA in it's chain.
What am I getting wrong here?
You are not getting anything wrong at all. The pinning configuration you choose comes down to a compromise between the level of security that you are comfortable with and practicality. There are 3 options and trade-offs:
Pin to leaf certificates (Maximum security)
You have full control and ownership of everything and no outside influence can compromise your SSL without compromising your infrastructure. Further, the compromise of any one of your certificates will not impact the others.
The downside here is that it will require a good deal of sensitive infrastructure to issue, audit, manage and deploy more than a few dozen certificates. Consider a publisher with 5,000 SSL certificates across various magazine and news properties.
Pin to an intermediadary CA that you own (Very High Security)
Effectively similar benefits of pinning to leaf certificates, except here if your intermediary certificate is compromised, all issued certificates are compromised. This is a balanced approach for pinning a huge number of SSL certificates.
Downside is that it’s incredibly expensive to obtain one of these.
Pin to a trusted root CA (High Security)
If you pin to a root CA or intermediate CA that you don’t own, you are in effect handing the keys to the owner of that certificate. This does mean that you are accepting any certificate that the root or intermediate issues for your domain. However, the reality is that this may be sufficient security to thwart most attacks. The business model of a mature global authority is predicated on trust. It is unlikely that a root CA will issue a malicious certificate for your domain.
A few downsides here:
CA Employees – In rare cases CA employees have been known to do bad things.
State Actors – We have no idea if governments have been able to get global authorities to issue malicious certificates. Perhaps even without them knowing via extralegal domestic espionage.
In the end, the most common strategy tends to be pinning to 2 or 3 trusted certificate authorities. When any one CA is compromised or breaks, you have other trusted certificates already issued and ready to go.
Here's a blog post with a section about the backup pin: https://noncombatant.org/2015/05/01/about-http-public-key-pinning/
Specifically:
You could, and likely should, also use an alternate intermediary or root issuer certificate for your backup. Additionally, it is best to get your backup signed by a valid issuer, before disaster strikes, so that you really can put it into production at a moment’s notice!
For your App, you should pin the root CA of the server's current certificate (GeoTrust Global CA) and then buy a certificate from a different CA and use that other CA as the backup pin. Pinning the leaf certificate (myServer.com) is more work to manage as this certificate's key is going to change more often that the root's.
Also, the most important thing about the backup pin is that it should be for a completely different certificate chain.
We're attempting to follow the Apple docs for using your own certificate authority (CA):
While a self-signed certificate is a reasonable approach during
development, there is a better way: create your own certificate
authority ... and have it issue a certificate for your test server.
You can then ... hard-wire your certificate authority's root
certificate into your app
I haven't been able to figure out how to hard wire the CA root cert using Swift. The paper mentions an approach but I haven't been able to translate this into Swift code:
Get a copy of the remote peer's certificate ...
Get the server
certificate from the trust object (pass an index of 0 to
SecTrustGetCertificateAtIndex)
Get the data for that server
certificate (SecCertificateCopyData)
Compare this to the certificate
data you got in step 1; if they match, you're talking to the correct
peer
How can you do this via Swift?
As per my understanding, SSL Pinning is to compare the public key or certification of a server with the copies bundled in the client beforehand.
I saw in Stackoverflow that many developers use SSL Pinning by AFNetwork libraries, but most of them use it along with a self-signed certificate.
I have bought a valid certificate from a CA and passed the test to verify it worked fine. I mean, I set the following and it worked
...
_sharedHttpsInstance.securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeNone];
_sharedHttpsInstance.securityPolicy.allowInvalidCertificates = NO;
...
What I am wondering is that if set the Pinning mode to AFSSLPinningModePulicKey, my application would be more secure in communication with the server in addition to what the valid certificate have provided?
thanks a lot.
I'm don't know the exact implementation of SSL pinning in iOS, but in principle pinning provides definitely more security than the default verification against a set of builtin certificate agencies. By default systems trust more than 100 different CA from all over the world and each of the CA has the ability to issue any certificate it wants, even if another CA has already issued the same or a similar certificate. So if any of these 100+ CAs gets compromised they can issue a certificate for your domain, which would pass the checks in your application unless you use certificate pinning. Such compromises happened in 2011 with DigiNotar (no longer existent because of that) and Comodo (was too big to fail).
Probably the most prominent user of certificate pinning is Google Chrome, where it is used for the google domains and this helped to detect the compromises of DigiNotar and Comodo.
A downside of certificate pinning might be, that the application will stop working inside networks which do SSL interception for security reasons. Google Chrome seems to deal with this situation by accepting the certificate if it is signed by a CA explicitly added by the user (i.e. no builtin) alternatively to the pinning checks.
Another question which might be interesting is if SSL pinning is secure 'ENOUTH' for 'Most' of the application, even if working along with self-signed certification?
Checking against a fixed certificate or public key (e.g. certificate pinning with or without self-signed) is more secure than only checking if the certificate is signed by any of the 100s CAs trusted by the system. And as long as the developer has full control about both sides (e.g. application and server) it also scales well. The only advantage of additionally using the usual infrastructure is the use of the certificate revocation mechanism. But because the developer has control of the application (s)he could just replace the appplication in case the certificate gets compromised. So yes, in most cases it is secure enough do do SSL pinning with a self-signed certificate and it is more secure than using the standard certificate validation without pinning.
It's very difficult to say categorically whether pinning is better or worse, since it shifts the risk to a different party.
Pinning will essentially protect you better against a potential breach in any of the CA you trust. If a CA is compromised and made to issue a certificate for the host you're trying to contact, pinning will protect you against that because you will compare with the specific reference you've pinned, instead of going through the CA.
The downside is that it will prevent you from using the mechanisms in place at the CA to deal with a compromised host: certificate revocation. If the host's private key is compromised, going through the PKI verification mechanism should allow you to check for revocation, and be warned that such a problem happen. In contrast, you won't be able to know that with pinning, since you're not going through the CA to check the certificate at all.
Of course, you could combine both approaches, but this could cause additional problems (you'd need a strategy to deal with conflicting outcomes in both evaluations, otherwise a compromised CA revoking a valid cert could cause a DoS).
I don't know whethet AFNetworking's pinning mechanism replaces the PKI validation or complements it.
In general, choosing between using pinning or PKI validation depends on whether you think that particular host's private key is more or less likely to be compromised than the CAs you trust.
Another downside of pinning is that you need to update the application (or let the user "re-pin") every time the server certificate (or at least the key-pair, depending on what you've pinned) is changed legitimately. It's probably not a bad idea to re-key once in a while.
(To be clear, I'm not saying that CAs are better, just that pinning changes the set of problems.)
You hear a lot about how you can use SSL pinning to increase the security in your app. I was always under the assumption that SSL pinning is only helpful if you use a self-signed cert. Are there benefits of SSL pinning when using a cert signed by a cert authority, or does the CA make that unnecessary?
SSL/TLS has some issues, and the root of those issues is the CA system. By default, your browser trusts a bunch of CAs. Other than a few basic checks such as hostname, etc, the real power of the SSL comes from the verification of the certificate via the intermediaries until you get to a certificate that you trust.
Certificate pinning specifies that you will only trust a given certificate for a given web site. That is to say, if you received a "valid" certificate signed by a different CA (even if you trusted that CA) you would not trust it for this site.
In short, the fact that the CA has signed a cert does not reduce the need for certificate pinning.
For example: Companies sometimes intercept SSL. To do this, they actually serve the client a different SSL certificate that is valid for the host that the client is trying to access. Because they can insert any certificate into the trusted root (windows via GPO) they can insert their certificate instead of the actual one issued by the host. In this scenario, the SSL interception is transparent to the user. They are still being issued a "valid" certificate that is signed by a CA they trust (whether they know it or not). If you had been using certificate pinning, the new cert would be rejected.
There are cons to certificate pinning, mostly around the management of the cert as it expires etc.
See this link for more info.