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.
Related
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.
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.)
I have a cert signed by a CA (Geotrust) on my server. I have the same cert installed in my app. I compare the two certs in URLSession:didReceiveChallenge:completionHandler:. But I was notified by my hosting service that I need to 'renew' the cert each year. That creates a new and different cert for me to handle in the app. Since the certs are not self-signed, do I need to embed the cert in the app for comparison with the cert as it comes from the server or does iOS's SSL handling take care of the challenge for me. Maybe I can just use server trust without looking at the cert?
I have the same cert installed in my app.
Why?
I compare the two certs in URLSession:didReceiveChallenge:completionHandler.
Why?
What you should be doing is comparing the subjectDN. That's what the signer is verifying. It's all you need.
Maybe I can just use server trust without looking at the cert?
It sounds like you're trying to do the correct thing and add an authorization step. Relying on 'server trust' just gives you authentication, i.e. the subject DN is who he says he is. Authorization checks whether that DN is authorised to use this part of the application. But you don't need to check the entire certificate for that.
I am developing mdm server and I have a problem with one of enrollment steps. The problem is scep step. I implement a scep server which handles Device CACert request and sends our server certificate in der format. After that, device sends encrypted and signed csr. But I can not verify signature of message. I think device creates a self-signed-certificate and sign message with it. We think that because signature certificate's common name is changing each "PKIOperation" request. But we must verify this signature because of security.
For example in each 3 enrollment request, certificate of csr signature changes. Their common names are:
CN=6E4F65AD-1E64-4E4D-A96E-2039EB140041
CN=2E33C2CC-14B8-47AC-938B-DCC7F8DA8715
CN=6817ED48-AB79-4FF0-A1A9-42C2AC303672
Note: The other steps of enrollment device sign messages with proper certificate and I can verify them. Only scep PKIOperation request is my problem. Is there any profile flag to set or something to solve this problem?
I may be wrong in some details, because I touched this about two years ago.
However, as I remember it's part of a protocol
If you take a look at SCEP draft: https://datatracker.ietf.org/doc/html/draft-nourse-scep-23#page-30 you will see this:
When building a pkiMessage, clients MUST have a certificate to sign
the PKCS#7 [RFC2315] signed-data (because PKCS#7 [RFC2315] requires
it). Clients MUST either use an existing certificate, or create a
self-signed certificate (see Section 2.3).
If the requester does not have an appropriate existing
certificate, then a locally generated self-signed certificate
MUST be used instead. The self-signed certificate MUST use the
same subject name as in the PKCS#10 request.
However, I was under impression that iOS device uses certificate/private keys which are built into the device. And this certificate is signed using Apple certs. And actually, as I remember they had exactly the format of CN, which you shown.
So, generally speaking it's ok if device uses self-signed certificate for first communication to the SCEP server (PKIOperation) and uses a certificate issued by your CA later on.
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.