oooO ↘┏━┓ ↙ Oooo
( 踩)→┃你┃ ←(死 )
\ ( →┃√┃ ← ) /
_)↗┗━┛ ↖(_/
我觉得https是iOS开发者要踩的最大的一个坑了,每每看他人写的博客都是只讲理论贴代码,却没有一篇是教你一步一步实现,是不是很头大呢。今天来一步一步实现https的正确验证,后面再讲不正确的验证。
步骤:
1.生成私钥 > 生成签名 > 生成证书(服务器端) > 生成证书(iOS端)
2.服务器端设置https接口。(node)
3.iOS端设置证书验证。
Demo
证书
//生产私钥
$ openssl genrsa 2048 > rsa_private_key.pem
//由私钥生产证书请求(签名)
$ openssl req -new -key rsa_private_key.pem -out certificate_request.csr
//通过私钥文件和CSR证书签名生成证书文件(服务器证书)
$ openssl x509 -req -days 365 -in certificate_request.csr -signkey rsa_private_key.pem -out cert.crt
//转换证书(iOS端证书)
$ openssl x509 -in cert.crt -out cert_ios.cer -outform der
//此时得到了我们需要的三个文件
rsa_private_key.pem(私钥)
cert.crt(证书用于服务器端)
cert_ios.cer(证书用于iOS端)
服务器端设置(Node)
需将rsa_private_key.pem 和 cert.crt拷贝至项目中
//index.js
var https = require('https');
var fs = require('fs');
var options = {
key: fs.readFileSync('./rsa_private_key.pem'),
cert: fs.readFileSync('./cert.crt')
};
var params = {
hi : 'Hello World!',
hello : 'Hello Node!'
}
var server = https.createServer(options ,function(req, res){
res.writeHead(200, {'Content-Type': 'application/json'});
res.end(JSON.stringify(params));
}).listen(3000);
//启动服务
$ node index.js
iOS端设置(Xcode)
需将cert_ios.cer拷贝至项目中
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
//AFSSLPinningModeCertificate模式与AFSSLPinningModePublicKey模式都会加载项目中所有的.cer后缀的证书文件来进行校验。AFSecurityPolicy需要使用一下方法创建。
manager.securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate];
//允许使用无效证书(自建证书)
manager.securityPolicy.allowInvalidCertificates = YES;//默认NO
//不需要域名验证
manager.securityPolicy.validatesDomainName = NO;//默认YES
[manager GET:@"https://127.0.0.1:3000" parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
NSLog(@"%@",responseObject);
//将打印:hi : 'Hello World!', hello : 'Hello Node!'字典
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
}];
详解
iOS 开发笔记-AFNetWorking https SSL认证
错误用法
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
//AFSSLPinningModeNone模式下设置以下属性将不验证服务器证书真伪。虽然一样能获取解析数据,但对于客户端来说是不安全的。
manager.securityPolicy.allowInvalidCertificates = YES;//默认NO
manager.securityPolicy.validatesDomainName = NO;//默认YES
[manager GET:@"https://127.0.0.1:3000" parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
NSLog(@"%@",responseObject);
//将打印:hi : 'Hello World!', hello : 'Hello Node!'字典
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
}];