TrustKit
TrustKit是一个开源框架,可以轻松地在任何iOS 12+、macOS 10.13+、tvOS 12+或watchOS 4+应用中部署SSL公钥固定和报告功能;它支持Swift和Objective-C应用。
如果你需要在Android应用中使用SSL固定/报告功能,我们还发布了TrustKit for Android,地址为https://github.com/datatheorem/TrustKit-Android。
概述
TrustKit提供以下功能:
- 简单的API,用于配置SSL固定策略并在应用中强制执行。策略设置主要基于HTTP公钥固定规范。
- 通过固定证书的主体公钥信息来实现合理的实现,而不是固定证书本身或公钥位。
- 报告机制,用于在检测到意外证书链时通知服务器应用内发生的固定验证失败。这类似于HPKP规范中描述的_report-uri_指令。通过利用TrustKit发送的固定验证通知,还可以在应用内自定义报告机制。
- 通过调整应用的_NSURLConnection_和_NSURLSession_代理来实现自动固定功能,从而自动为应用的HTTPS连接添加固定验证;这允许在不修改应用源代码的情况下部署TrustKit。
入门指南
- 阅读[入门指南][getting-started]。
- 查看[API文档][api-doc]。
- TrustKit最初在[2015年美国黑帽大会][bh2015-pdf]上发布,并在[PayPal的工程博客][paypal-post]上也有介绍。
使用示例
在应用中部署SSL固定需要使用固定策略(域名、主体公钥信息哈希和其他设置)初始化TrustKit。
策略可以在应用的Info.plist
中配置:
另外,也可以通过编程方式设置固定策略:
NSDictionary *trustKitConfig =
@{
kTSKSwizzleNetworkDelegates: @NO,
kTSKPinnedDomains : @{
@"www.datatheorem.com" : @{
kTSKExpirationDate: @"2017-12-01",
kTSKPublicKeyHashes : @[
@"HXXQgxueCIU5TTLHob/bPbwcKOKw6DkfsTWYHbxbqTY=",
@"0SDf3cRToyZJaMsoS17oF72VMavLxj/N7WBNasNuiR8="
],
kTSKEnforcePinning : @NO,
},
@"yahoo.com" : @{
kTSKPublicKeyHashes : @[
@"TQEtdMbmwFgYUifM4LDF+xgEtd0z69mPGmkp014d6ZY=",
@"rFjc3wG7lTZe43zeYTvPq8k4xdDEutCmIhI5dn4oCeE=",
],
kTSKIncludeSubdomains : @YES
}
}};
[TrustKit initSharedInstanceWithConfiguration:trustKitConfig];
在Swift应用中也可以通过编程方式设置策略:
let trustKitConfig = [
kTSKSwizzleNetworkDelegates: false,
kTSKPinnedDomains: [
"yahoo.com": [
kTSKExpirationDate: "2017-12-01",
kTSKPublicKeyHashes: [
"JbQbUG5JMJUoI6brnx0x3vZF6jilxsapbXGVfjhN8Fg=",
"WoiWRyIOVNa9ihaBciRSC7XHjliYS9VwUGOIud4PB18="
],]]] as [String : Any]
TrustKit.initSharedInstance(withConfiguration:trustKitConfig)
初始化TrustKit后,可以从TrustKit单例中获取一个TSKPinningValidator
实例,并在应用的网络代理中使用它来执行SSL固定验证。例如在NSURLSessionDelegate中:
- (void)URLSession:(NSURLSession *)session
task:(NSURLSessionTask *)task
didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge
completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler {
{
TSKPinningValidator *pinningValidator = [[TrustKit sharedInstance] pinningValidator];
// 将认证挑战传递给验证器;如果验证失败,连接将被阻止
if (![pinningValidator handleChallenge:challenge completionHandler:completionHandler])
{
// TrustKit没有处理这个挑战:可能不是服务器信任
// 或者域名没有被固定。回退到默认行为
completionHandler(NSURLSessionAuthChallengePerformDefaultHandling, nil);
}
}
更多信息,请参阅[入门指南][getting-started]。
致谢
TrustKit是Data Theorem和Yahoo移动团队的联合努力成果。详情请参阅AUTHORS
文件。
许可证
TrustKit基于MIT许可证发布。详情请参阅LICENSE
文件。
[入门指南]: https://github.com/datatheorem/TrustKit/blob/master/docs/getting-started.md
[BH2015-PDF]: https://github.com/datatheorem/TrustKit/blob/master/docs/TrustKit-BH2015.pdf
[BH2015会议]: https://www.blackhat.com/us-15/briefings.html#trustkit-code-injection-on-ios-8-for-the-greater-good
[API文档]: https://datatheorem.github.io/TrustKit/documentation
[iOS9文章]: https://datatheorem.github.io/ios/2015/10/17/trustkit-ios-9-shared-cache/
[PayPal文章]: https://www.paypal-engineering.com/2015/10/14/key-pinning-in-mobile-applications/