Would iOS AFNetwork SSL Pinning mode provide additional security bonus if valid certificate deployed - ios

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.)

Related

Self signed certificate in production environment for internal HTTPS calls?

I have generated a self signed certificate .This self signed certificate is stored in server and accepts request only from clients which is having this self signed certificate is this acceptable. since this HTTPS endpoint is supposed to be used only from our custom HTTPS client I strongly feel that CA signing is not required .
But my colleagues are warning that Self signed certificate should not be used in production environment no matter what .what should I do ??
There is a whole infrastructure in place to manage the life-cycle of the certificates, it is called PKI (Public Key Infrastructure). The CA's are part of it, and help you manage the certificate issuance and revocation.
It is not advised to use self-signed certificates in production environment, because you loose the life-cycle management of the certificate. Lets say if the client is compromised, any one in possession of that self-signed certificate can talk to the server. There is no way you can manage to revoke that certificate or maintain the CRL.
The ideal solution/implementation in your case, will actually be issuing the clients their own PKCS12 from the CA as well, which means they will have their own private key (this might get expensive, if you have many clients). But this is most secure way of doing it. If you know a client is compromised, you can revoke that client's certificate from the CA, and if the client does certificate validation (ideally should), it should no longer be able to communicate with the server. You can simply decommission that client.
Just an idea
But if you are looking for cost effective way (since you mentioned internal calls), you could have your server issue P12's to the clients, and your server maintaining a record of which client has what certificate. This gives you little control of managing the clients. You could enable certificate based authentication on the server side for those services (the server will receive the subjectDN of the client), and by referring to the stored record, you can identify which client is trying to communicate. And if you want to disable that client from being served by the server, simple update the record.
But to answer your concern, it is not ideal to use self-signed certificate because, in real world, you should be able to manage the certificates in real time or near to real time, which will not be possible if you use self-signed certificates.

Difference between SSL pinning and certificate validating

Can someone explain the difference between validating a certificate like described with a self-signed certificate here:
https://jetforme.org/2013/05/validating-a-self-signed-ssl-certificate-in-ios-and-os-x-against-a-changing-host-name/
and SSL pinning like described here:
https://infinum.co/the-capsized-eight/how-to-make-your-ios-apps-more-secure-with-ssl-pinning
What does SecPolicyCreateSSL means?
What in detail is SecTrustEvaluate doing?
Is the procedure in the first link including SSL pinning?
If not, is it a good idea to implement both?
Thanks
First let's clarify the terminology in the Cocoa world:
A SecPolicyRef is a policy that defines the rules when validating a certificate chain: the things to check for in the certificates within the chain (signature, expiration date, etc.), which determine whether the certificate chain is valid/trusted or not.
A SecTrustRef object is the combination of a certificate chain (basically an array of SecCertificateRef) and a SecPolicyRef. This object represents all the things needed to validate a certificate chain (the certificates + the policy).
Validating a server's certificate chain involves two steps:
The certificate path needs to be validated (the signatures, the expiration date, etc.) to ensure that the server certificate was issued by a trusted CA.
The name for which the server certificate was issued (Common Name or Subject Alternative Name) needs to match the name of the server the App is trying to connect to.
These steps are expressed by a SecPolicyRef:
SecPolicyCreateBasicX509() returns a policy that has all the things to check for 1; this is there for historical reasons but it should never be used.
SecPolicyCreateSSL() returns a policy that has all the rules for both 1 and 2; this is the one you must use.
You then use SecTrustEvaluate() to validate the server's SecTrustRef. The result will tell you if the server's certificate chain is trusted based on the SecPolicyRef that was passed.
Lastly, SSL pinning means adding a third step to this whole process:
The certificate chain must contain a specific key or certificate. This ensures that only the certificate you know you deployed on your servers will be accepted by the App, instead of any certificate issued by any CA for your domain.
I would advise against writing your own implementation of SSL validation (with or without pinning) as, you can tell, the APIs are extremely complex and there is a big potential for huge mistakes that would make your extremely App insecure.
I have worked on a library to make it easy to do SSL pinning; it's available at https://github.com/datatheorem/TrustKit and takes care of all the heavy lifting.

How to get a backup pin for TrustKit framework's SSL pinning under iOS?

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.

RESTful Service with Self Signed SSL

We are building an end to end solution that will allow our customers to access their ERP data hosted in their own servers through mobile applications. Version 1 will be an iOS app.
We need to make sure the traffic between the client and the server is encrypted with SSL. The problem lies in that we want the installation of the server to be as seamless as possible, hence we don't want the customer to go through the process of buying and installing SSL Certificates. Not even mentioning having to renew that certificate every year.
We were thinking of creating a self signed CA certificate and use it to create child certificates for each client to install on their servers (along with the public CA certificate). We would automate the process of creating the child certificate and include it as part of the setup process. The certificate will also have a very long expiration date as to not dealing with expirations. But if we use this certificate the requests from the client won't be trusted as the CA won't be trusted.
Can the CA be added to the iOS app or device?
Is there a security concern with this implementation?
I have a very similar situation. So far I have just created self signed certificates and just programmed the clients to ignore allow untrusted SSL certificates. If there is a better answer I'd love to hear it.
It is 2017 and letsencrypt now exists, which provides free domain validation and signing of TLS certificates such that browsers / OS HTTPS or TLS libraries and frameworks will accept them, and through certbot it is relatively easy to set up auto-renewal. I won't describe it here because it's deployment specific, but they have good docs. Combined they're probably the best solution out there.
Bundling and using self-signed certificates is seriously sub-optimal for various reasons, and there's no reason to do it anymore (except perhaps gross laziness), so don't.
Free is only for basic domain-validated certificates, i.e. where letsencrypt.org validates that you own the domain that you say you do (and certbot is used to automate that process). You still need to pay for extra verification steps if you want them. However, for internal TLS connections between your app and your server, you only really need domain validated, because you only have to be sure you are talking to your server. The extra steps are more focussed on giving a customer confidence in a company, so they can give over sensitive data with greater peace of mind. Generally speaking if they are using you app, that suggests they trust your company already, so the extra validation is not important (and probably invisible to the customer anyway).
In development if you want to use self-signed certificates this may still make sense. Check out my answer to this question on how to install self-signed certificates for all apps on your iOS device.

What to use for public key certificate validation, Certificate Depository via LDAP or an OCSP responder?

So i was sniffing through the pages of PKI's Overview by Joel Weise (http://highsecu.free.fr/db/outils_de_securite/cryptographie/pki/publickey.pdf) and one thing i didn't quite get is, when to use an OCSP responder over LDAP for checking up the validity of a given certificate ? Say some CA exposes both - when to use the OCSP service, when to use the Certificate Depositories LDAP servers ?
It might be helpful to think this way.
The Certificate Authority generates certificate revocation lists (CRLs). (You could query the CA directly but this is a bad idea due to risk of exposing private keys (secrets)).
The CRLs can then be made available via LDAP or HTTP. (if you have a small deployment you can likely stop here)
An OCSP server (or validation authority depending on the vernacular) can also consume CRLs. Once it does so it can handle validation (certificate status) requests. (if you have a larger deployment and handling CRLs is cumbersome you might consider this option)
There are options (3rd parties, e.g. not Microsoft) for there to be distributed OCSP responders that have pre-signed the responses and then forward and store (as opposed to multiple OCSP servers). (consider if you still have a relatively larger deployment and where you have network availability, scale, loading issues as another option).
Finally make sure that you are not only checking certificate status but also certificate trust. In federated environments you may want to consider the Server Certificate Validation Protocol (SCVP) as a complement to the above.

Resources