2013-05-22 47 views
6

Để cải thiện bảo mật của ứng dụng và bảo vệ người dùng khỏi các cuộc tấn công MITM Tôi đang cố gắng thực hiện SSL bằng chứng chỉ tự ký của mình theo nội dung của this post.Ghim SSL trên iOS

Vì vậy, tôi đang sử dụng mã sau để so sánh chứng chỉ mà tôi nhận được từ máy chủ với chứng chỉ đi kèm trong ứng dụng.

- (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]; 
    } 
} 

Những điều duy nhất mà là khác nhau giữa mã của tôi và một trong các bài viết trên blog tôi liên kết là tên và phần mở rộng (cer để .crt) cho tài nguyên đại diện cho giấy chứng nhận của tôi và hai NSLogs tôi đã thêm sẽ có ích sau này để cho biết vấn đề là gì.

Trong thực tế khi mã này được thực thi tôi nhận được kết quả này:

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 

Rõ ràng là so sánh giữa các địa phương và giấy chứng nhận từ xa không thành công vì chiều dài của dữ liệu là khác nhau và vì vậy nó cũng thất bại các ghim.

Tại sao điều này xảy ra và làm cách nào tôi có thể giải quyết vấn đề này?

+1

Bạn đã xem xét việc lưu dữ liệu chứng chỉ đã trả về vào một tệp và sử dụng? Nếu không, làm một sự khác biệt trên dữ liệu và xem những gì khác nhau. –

+0

Không, tôi không nghĩ về điều đó! Ý tưởng hay, tôi sẽ thử ngay lập tức! – BigLex

+0

Nếu bạn đang sử dụng Alamofire, hãy kiểm tra http://jayprakashdubey.blogspot.in/2017/07/ssl-pinning-in-ios-swift-code.html này –

Trả lời

5

Tôi gặp vấn đề tương tự. Vấn đề có thể là do bạn chưa chuyển đổi tệp .crt của bạn thành định dạng đúng. iOS & OSX đang tìm kiếm chứng chỉ của bạn ở định dạng .der. Bạn cần sử dụng openssl để chuyển đổi. Here là một bài viết rất hữu ích về chủ đề này. Chứng chỉ công khai của tôi đến từ máy chủ Apache (tôi giả sử rằng máy chủ của bạn cũng đã làm). Sau khi xem qua tài liệu openssl, tôi đã có thể tìm ra cách để làm việc này.

1) Mở Terminal và thay đổi thư mục thành vị trí của tệp .crt của bạn.

2) Thực hiện lệnh này:

openssl x509 -in your_cert.crt -outform der -out your_output_name.der 

này sẽ tạo ra một tập tin đầu ra có tên là 'your_output_file.der'. Bạn phải nhập này vào dự án Xcode của bạn và tham khảo nó trong các phương pháp

- (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge 

thực hiện NSURLConnectionDelegate của bạn.

Tôi hy vọng điều này sẽ hữu ích!