
最近公司产品在搞加强安全,所以有必要先了解一下HTTPS。这里只是找了两篇文章写的很好。特此拿来存到个人博客里。以便以后复习。域名ssl证书
1.HTTPS传输流程
2.常用加密算法
3.AFN证书校验策略及核心方法
4.SSL Pinning
5.CA证书申请流程
HTTPS经由超文本传输协议进行通信,但利用SSL/TLS来对数据包进行加密。HTTPS开发的主要目的,是提供对网络服务器的身份认证,保护交换数据的隐私与完整性

由于不相信服务器生成的随机数,所以需要客户端生成pre-master-securet,然后再由服务端加密,最后得到master-securet(主密钥),建立密道通信。(减少被猜中的可能)
非对称加密算法:RSA,DSA/DSS
对称加密算法:AES,R,3DES
HASH算法:MD5,SHA1,SHA256
非对称加密算法用于握手过程中的加密生成的密码,
对称加密算法用于对真正传输的数据进行加密,
HASH算法用于验证数据的完整性,是否被篡改等

非对称加密生成密码是整个加密过程的关键,非对称加密会生成公钥和私钥,
公钥负责数据加密,(可以随意传输)
私钥负责解密,(重中之重)
NSURLSession 封装了HTTPS链接的建立加密解密功能,但并没有验证证书的合法性,无法避免中间人攻击,要真正的安全通讯,需要我们手动去验证证书,
客户端校验策略
sessionManager.securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeNone];
* AFSSLPinningModeNone 不做SSL pinning 只信任证书颁发机构证书,自己生成证书不通过
* AFSSLPinningModeCertificate 客户端保存证书拷贝 第一步验证证书的域名/有效期等信息,第二步是对比服务端返回的证书跟客户端返回的是否一致。
* AFSSLPinningModePublicKey 客户端保存证书拷贝 只是验证时只验证证书里的公钥,不验证证书的有效期等信息
核心证书校验方法
- (BOOL)evaluateServerTrust:(SecTrustRef)serverTrust forDomain:(NSString *)domain
{
// **** AFSSLPinningModeNone 不做SSL Pinning 当需要使用证书验证域名时,需要使用AFSSLPinningModePublicKey或AFSSLPinningModeCertificate
if (domain && self.allowInvalidCertificates && self.validatesDomainName && (self.SSLPinningMode == AFSSLPinningModeNone || [self.pinnedCertificates count] == 0)) {
// According to the docs, you should only trust your provided certs for evaluation. Pinned certificates are added to the trust. Without pinned certificates, there is nothing to evaluate against.
/*
From Apple Docs:
"Do not implicitly trust self-signed certificates as anchors (kSecTrustOptionImplicitAnchors). Instead, add your own (self-signed) CA certificate to the list of trusted anchors."
*/
NSLog(@"In order to validate a domain name for self signed certificates, you MUST use pinning.");
return NO;
}
NSMutableArray *policies = [NSMutableArray array];
//**** 需要验证域名时,添加一个域名验证策略
if (self.validatesDomainName) {
[policies addObject:(__bridge_transfer id)SecPolicyCreateSSL(true, (__bridge CFStringRef)domain)];
} else {
[policies addObject:(__bridge_transfer id)SecPolicyCreateBasicX509()];
}
//**** 设置验证策略
SecTrustSetPolicies(serverTrust, (__bridge CFArrayRef)policies);
if (self.SSLPinningMode == AFSSLPinningModeNone) {
//**** AFSSLPinningModeNone 时,allowInvalidCertificates为YES ,则代表服务器任何证书都能验证 **** 如果是NO,则需要判断此服务器是否是系统信任证书
return self.allowInvalidCertificates || AFServerTrustIsValid(serverTrust);
} else if (!AFServerTrustIsValid(serverTrust) && !self.allowInvalidCertificates) {
// **** 如果服务器证书不是系统信任证书,且不允许不信任证书通过验证则返回NO
return NO;
}
switch (self.SSLPinningMode) {
case AFSSLPinningModeNone:
default:return NO;
case AFSSLPinningModeCertificate:
{
//**** AFSSLPinningModeCertificate 是直接将本地证书设置为信任的根证书,然后来进行判断,并且比较本地证书内容和服务器证书内容是否一致,如果有一个相同则返回YES
NSMutableArray *pinnedCertificates = [NSMutableArray array];
for (NSData *certificateData in self.pinnedCertificates) {
[pinnedCertificates addObject:(__bridge_transfer id)SecCertificateCreateWithData(NULL, (__bridge CFDataRef)certificateData)];
}
// **** 设置本地证书为根证书
SecTrustSetAnchorCertificates(serverTrust, (__bridge CFArrayRef)pinnedCertificates);
//**** 通过本地证书来判断服务器证书是否可信,不可信则不通过
if (!AFServerTrustIsValid(serverTrust)) {
return NO;
}
// obtain the chain after being validated, which *should* contain the pinned certificate in the last position (if it's the Root CA)
NSArray *serverCertificates = AFCertificateTrustChainForServerTrust(serverTrust);
// **** 判断本地证书和服务器证书是否相同
for (NSData *trustChainCertificate in [serverCertificates reverseObjectEnumerator]) {
if ([self.pinnedCertificates containsObject:trustChainCertificate]) {
return YES;
}
} return NO;
}
case AFSSLPinningModePublicKey:
{
NSUInteger trustedPublicKeyCount = 0;
NSArray *publicKeys = AFPublicKeyTrustChainForServerTrust(serverTrust);
// **** AFSSLPinningModePublicKey 是通过比较证书中公钥部分来进行校验。通过SecTrustCopyPublicKey方法获取本地证书和服务器证书,进行比较,如果有一个相同则验证通过
for (id trustChainPublicKey in publicKeys) {
for (id pinnedPublicKey in self.pinnedPublicKeys) {
if (AFSecKeyIsEqualToKey((__bridge SecKeyRef)trustChainPublicKey, (__bridge SecKeyRef)pinnedPublicKey)) {
trustedPublicKeyCount += 1;
}
}
}
return trustedPublicKeyCount > 0;
}
} return NO;
}
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-70435-1.html
早安