To improve my app's security and protect the user from MITM attacks I'm trying to do SSL pinning with my self-signed certificate following the content of this post.
So I'm using the following code to compare the certificate that I get from the server with the one that bundled in the app.
- (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
SecTrustRef serverTrust = challenge.protectionSpace.serverTrust;
SecCertificateRef certificate = SecTrustGetCertificateAtIndex(serverTrust, 0);
NSData *remoteCertificateData = CFBridgingRelease(SecCertificateCopyData(certificate));
NSLog(@"Remote Certificate Data Length: %d",[remoteCertificateData length]);
NSString *cerPath = [[NSBundle mainBundle] pathForResource:@"apache" ofType:@"crt"];
NSData *localCertData = [NSData dataWithContentsOfFile:cerPath];
NSLog(@"Local Certificate Data Length: %d",[localCertData length]);
if ([remoteCertificateData isEqualToData:localCertData]) {
NSURLCredential *credential = [NSURLCredential credentialForTrust:serverTrust];
[[challenge sender] useCredential:credential forAuthenticationChallenge:challenge];
}
else {
[[challenge sender] cancelAuthenticationChallenge:challenge];
}
}
The only things that are different between my code and the one in the blog post I linked are the name and the extension (.cer to .crt) for the resource representing my certificate and the two NSLogs I added that will come handy later to show what the problem is.
In fact when this code is executed I get this output:
2013-05-22 16:08:53.331 HTTPS Test[5379:c07] Remote Certificate Data Length: 880
2013-05-22 16:09:01.346 HTTPS Test[5379:c07] Local Certificate Data Length: 1249
Obviously the comparison between the Local and the Remote certificates fails because the length of the data is different and so it also fails the pinning.
Why does this happen and how could I solve this problem?
Now go to Settings > SSL Kill Switch 2. Enable the Disable Certificate Validation setting. Begin exploring the app on your iOS device and notice how the traffic is captured by the Burp Suite. Let's open the DVIA V2 application and test it.
If you want to turn on SSL/TLS trust for that certificate, go to Settings > General > About > Certificate Trust Settings. Under "Enable full trust for root certificates," turn on trust for the certificate. Apple recommends deploying certificates via Apple Configurator or Mobile Device Management (MDM).
I had the same issue. The problem is probably because you have not converted your .crt file to the correct format. iOS & OSX are looking for your certificate to be in .der format. You need to use openssl to convert it. Here is a very helpful article on this topic. My public certificate came from an Apache server (I am assuming that yours did as well). After looking over openssl documentation I was able to figure out how to get this to work.
1) Open Terminal and change directory to the location of your .crt.
2) Execute this command:
openssl x509 -in your_cert.crt -outform der -out your_output_name.der
This will create an output file named 'your_output_file.der'. You must import this into your xCode project and reference it in the
- (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
method of your NSURLConnectionDelegate
implementation.
I hope this helps!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With