12/08/2018, 15:56

Viết ứng dụng iOS an toàn hơn với SSL Pinning

SSL (Secure Socket Layer) đảm bảo truyền thông giữa client-server được mã hóa qua HTTP - HTTPS (HTTP over SSL). Mã hóa dựa trên PKI (Public Key Infrastructure) và một session key. Session key đã được giới thiệu bởi vì việc mã hóa và giải mã một public/private tốn rất nhiều tài nguyên CPU và nó sẽ ...

SSL (Secure Socket Layer) đảm bảo truyền thông giữa client-server được mã hóa qua HTTP - HTTPS (HTTP over SSL). Mã hóa dựa trên PKI (Public Key Infrastructure) và một session key. Session key đã được giới thiệu bởi vì việc mã hóa và giải mã một public/private tốn rất nhiều tài nguyên CPU và nó sẽ làm chậm toàn bộ quá trình truyền thông.

Thay vì phải mã hóa bất đối xứng dữ liệu tại nguồn và giải mã nó ở đích, một khoá phiên đối xứng, được trao đổi thông quan giao thức SSL Handshake khi giao tiếp bắt đầu được sử dụng.

SSL không phải là một giao thức đơn lẻ, mà là một tập các thủ tục đã được chuẩn hoá để thực hiện các nhiệm vụ bảo mật sau:

  • Xác thực server: Cho phép người sử dụng xác thực được server muốn kết nối.
  • Xác thực Client: Cho phép phía server xác thực được người sử dụng muốn kết nối.
  • Mã hoá kết nối: Tất cả các thông tin trao đổi giữa client và server được mã hoá trên đường truyền nhằm nâng cao khả năng bảo mật.

Chúng ta sử dụng SSL Pinning để đảm bảo rằng ứng dụng chỉ giao tiếp với chính máy chủ được chỉ định. Một trong những điều kiện tiên quyết là SSL Pinning đang chứa giấy chứng nhận SSL máy chủ được chấp nhận trọng App Bundle.

Chúng tôi sẽ giới thiệu SSL Pinning sử dụng thông qua AlamoFire và AFNetworking (sử dụng AFHTTPRequestOperationManager).

SSL Pinning sử dụng AlamoFire khá đơn giản. Truy xuất dự liệu chứng chỉ AlamoFire có phương thức ServerTrustPolicy.certificatesInBundle () trả về toàn bộ certificates trong Bundle. Đầu tiên chúng ta tạo ra đối tượng ServerTrustPolicy trong đó chúng ta nạp các certificate.

Tạo một đối tượng Manager cùng với SSL Pinning. Chúng ta cần cung cấp một đối tượng ServerTrustPolicyManager với kiểu dictionary. Nó maps những tên domain với ServerTrustPolicy

 self.serverTrustPolicies = [
            "github.com": self.serverTrustPolicy!
        ]

Điều này rất quan trọng. Trong AlamoFire chúng ta chỉ pinning các tên miên có sẵn những tên được phép truy cập trên server.

func configureAlamoFireSSLPinning {
        let pathToCert = NSBundle.mainBundle().pathForResource(githubCert, ofType: "cer")
        let localCertificate:NSData = NSData(contentsOfFile: pathToCert!)!

        self.serverTrustPolicy = ServerTrustPolicy.PinCertificates(
            certificates: [SecCertificateCreateWithData(nil, localCertificate)!],
            validateCertificateChain: true,
            validateHost: true
        )

        self.serverTrustPolicies = [
            "github.com": self.serverTrustPolicy!
        ]

        self.afManager = Manager(
            configuration: NSURLSessionConfiguration.defaultSessionConfiguration(),
            serverTrustPolicyManager: ServerTrustPolicyManager(policies: self.serverTrustPolicies)
        )
}

func alamoFireRequestHandler {
        self.afManager.request(.GET, self.urlTextField.text!)
            .response { request, response, data, error in
         // response management code
     }
}

Sử dụng SSL Pinning trong AFNetworking thì đơn giản và dễ hiểu hơn. Tất cả những gì bạn cần làm là gán một điều khoản thông qua phương thức policyWithPinningMode:AFSSLPinningModePublicKey cho AFHTTPRequestOperationManager

AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
AFSecurityPolicy *policy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModePublicKey];
manager.securityPolicy = policy;

Mặc định, AFNetworking sẽ kiểm tra trong bundle của bạn và check toàn bộ file ".cer", add chúng vào manager.securityPolicy.pinnedCertificates. Đó là lý do tại chúng ta không phải add chúng một cách thủ công. Tuy nhiên, nếu có một lý do để sử dụng một chứng chỉ cụ thể cho một mục đích cụ thể (thường có, khi chúng ta thêm nhiều mục tiêu vào dự án mà nói chuyện với các máy chủ khác nhau), chúng ta có thể thêm chúng như sau:

NSString *pathToCert = [[NSBundle mainBundle]pathForResource:@"github.com" ofType:@"cer"];
NSData *localCertificate = [NSData dataWithContentsOfFile:pathToCert];
manager.securityPolicy.pinnedCertificates = @[localCertificate];

Tất cả request tạo bằng các bằng AFHTTPRequestOperationManager sẽ sử dụng SSL Pinning khi giao tiêp với server.

Kết nối SSL được coi là an toàn và hiện tại đang được sử dụng rộng rãi. Bất kể một request nào việc mã hoá đều là cần thiết đặc biệt những ứng dụng có nguy cơ bị tấn công cao. SSL Pinning cho phép chúng ta định danh được máy chủ mà chúng ta kết nối có thực sự đáng tin cậy hay không.

Với SSL Pinning, chúng ta có thể từ chối tất cả các kết nối ngoại trừ những máy chủ có máy chủ được chỉ định mà chứng chỉ SSL chúng tôi đã lưu trong ứng dụng. Một hạn chế của SSL đó là khi chúng ta cập nhật SSL trên máy chủ hoăc SSL hết hạn hoặc vì một lý do nào đó thì chúng ta bắt buộc phải update client.

Với phiên bản iOS 9 trở đi đã giới thiệu thư viện ** App Transport Security**. ATS có thể reject tất cả các kết nối không an toàn nếu không sử dụng giao thức TLS 1.2 (Transport Layer Security ) hoặc SSL tương đương. (TLS được base trên SSL bên cạnh đó cũng có nhiều điểm khác nhau)

0