美文网首页
https证书验证

https证书验证

作者: Silence_xl | 来源:发表于2022-04-19 17:58 被阅读0次

废话开篇:https 证书是什么?如何进行认证呢?带着这些疑问来简单的实现一下验证过程

简单的了解一下 https 在数据传输前的一些操作,如图:

这里总结一下上面的流程图关键的步骤:

1、认证网络请求的安全性

服务器会在建立真正的数据传输之前返回一个公钥数字证书。这里客户端需要在 URLSession 进行认证挑战方法回调里进行判断然后确定是否要继续进行请求。代理方法如下:

- (void)URLSession:(NSURLSession *)session

              task:(NSURLSessionTask *)task

didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge

 completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler
复制代码

可以这样理解,URLSessionhttps 网络请求的时候其实会把请求鉴权的权限通过代理的方法给暴露出来,是否信任并继续建立连接可以按照特定规则去执行(如自签证书),只有 https 请求会走代理方法,http 则不进行回调,这也是为什么 iOS系统 为什么提倡使用 https 的原因。

2、认证通过,通过公私钥非对称加密方式对最后的对称加密密钥进行加、解密:

这话听起来有点绕,基于第一步的公钥数字证书信任,那么,生成一个用于请求数据对称加密的密钥(对称加密更快),用这个公钥进行非对称加密,在由服务器的私钥进行解密,得到这个密钥,那么,真正建立的数据传输就以此密钥进行加、解密。

下面,模拟一下如何进行的公钥证书受信

创建 公钥.der证书.cer 文件

在终端依次输入如下命令:


//生成私钥
openssl genrsa -out private_key.pem 1024

//获取 证书.cer
openssl req -new -key private_key.pem -out rsaCertReq.csr

openssl x509 -req -days 3650 -in rsaCertReq.csr -signkey private_key.pem -out rsaCert.crt

//将 .crt 格式证书转换为 .cer 格式证书,后面iOS程序里需要 .cer格式证书
openssl x509 -in rsaCert.crt -out rsaCert.cer -outform der

//获得 公钥.der
openssl x509 -outform der -in rsaCert.crt -out public_key.der

复制代码

过程中会有一些简单信息输入,这里没有特别的要求,文件创建后目录如图:

image.png

.cer 格式证书公钥.der 格式证书 全部拖到工程里:

image.png

下面输出一段代码,用 .cer 证书去验证 公钥.der 是否可信。


- (void)trustIsVaild

{
    //获取工程下所有cer证书(https 网络请求鉴权必需证书)
    NSArray *paths = [[NSBundle mainBundle] pathsForResourcesOfType:@"cer" inDirectory:@"."];

    //保存工程内的所有 cer 证书(并在后面设置为鉴权锚点)
    NSMutableArray *pinnedCertificates = [NSMutableArray array];

    for (NSString *path in paths) {

        NSData *certificateData = [NSData dataWithContentsOfFile:path];

        [pinnedCertificates addObject:( __bridge_transfer id)SecCertificateCreateWithData(NULL, ( __bridge CFDataRef)certificateData)];

    }

    //获取工程下的公钥数字证书(在https网络请求认证挑战中由服务器返回)
    NSString * publicKeyPath = [[NSBundle mainBundle] pathForResource:@"public_key" ofType:@"der"];

    NSData *derData = [[NSData alloc] initWithContentsOfFile:publicKeyPath];

    //证书资源
    SecCertificateRef myCertificate = SecCertificateCreateWithData(kCFAllocatorDefault, ( __bridge CFDataRef)derData);

    //验证政策设置
    SecPolicyRef myPolicy = SecPolicyCreateBasicX509();

    SecTrustRef myTrust;

    //SecTrust 赋值
    OSStatus status = SecTrustCreateWithCertificates(myCertificate,myPolicy,&myTrust);

    if (status == noErr) {
        //设置证书锚点(这里的意思就是如果鉴权到指定的证书是有效的,那么,就信任此公钥数字签名,这里如果不设置,那么就会一直找向根证书,由于工程里的公钥数字证书是自签的,所以,一定不会受信)
        SecTrustSetAnchorCertificates(myTrust, ( __bridge CFArrayRef)pinnedCertificates);

        SecTrustResultType result;

        if (SecTrustEvaluate(myTrust, &result) == 0) {

            //kSecTrustResultUnspecified 隐式信任 
            //kSecTrustResultProceed 可继续进行
            if ((result == kSecTrustResultUnspecified || result == kSecTrustResultProceed)) {

                NSLog(@"受信任的证书");

            } else {

                NSLog(@"未受信任的证书");

            }

        } else {

            NSLog(@"未受信任的证书初始化操作失败");

        }

    }

}
复制代码

运行如下:

image.png

顺便输出一下不设置 证书锚点 控制台内容:

if (status == noErr) {
        //不设置锚点
        //SecTrustSetAnchorCertificates(myTrust, (__bridge CFArrayRef)pinnedCertificates);

        SecTrustResultType result;

        if (SecTrustEvaluate(myTrust, &result) == 0) {

            if ((result == kSecTrustResultUnspecified || result == kSecTrustResultProceed)) {

                NSLog(@"受信任的证书");

            } else {

                NSLog(@"未受信任的证书");
            }
        } else {

            NSLog(@"未受信任的证书初始化操作失败");
        }
    }
复制代码
image.png

到这里,公钥证书如果受信,那么,下一步就规定一个 对称加密 session key 用这个公钥加密,发送到服务器,然后用对应的私钥解密,供以后的数据传输进行 对称加密 操作。

所以,移动端在做自定义证书鉴权的时候就需要存储服务器生成的 .cer 证书文件!

AFNetworking 下的鉴权方式处理相对复杂,因为 URLSession 的认证挑战回调是允许程序员全部无条件开启的,所以,AFNetworking 在默认鉴权行为的基础上添加了几种自定义鉴权方式:

typedef NS_ENUM(NSUInteger, AFSSLPinningMode) {

    AFSSLPinningModeNone,//无条件开启

    AFSSLPinningModePublicKey,//认证公钥内容

    AFSSLPinningModeCertificate,//认证证书

};
复制代码

而且,在此之前 AFNetworking 通过

@property (readwrite, nonatomic, copy) AFURLSessionTaskAuthenticationChallengeBlock authenticationChallengeHandler;
复制代码

暴露给外界闭包进行自定义鉴权逻辑及处理结果。

- (void)URLSession:(NSURLSession *)session

              task:(NSURLSessionTask *)task

didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge
 completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler
{
     BOOL evaluateServerTrust = NO;
     NSURLSessionAuthChallengeDisposition disposition = NSURLSessionAuthChallengePerformDefaultHandling;
     NSURLCredential *credential = nil;

     //AFNetworking 暴露给程序员自定义处理入口
     if (self.authenticationChallengeHandler) {
          id result = self.authenticationChallengeHandler(....);
          ... (解析处理结果)
     }
    ...(证书认证处理代码)

    //最后调用 completionHandler 继续执行操作
    if (completionHandler) {

        completionHandler(disposition, credential);

    }
}
复制代码

disposition: 可以设置继续鉴权挑战(NSURLSessionAuthChallengeUseCredential) 或者中断鉴权挑战(NSURLSessionAuthChallengeCancelAuthenticationChallenge

credential: 如果证书认证通过则直接进行赋值,

credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];
复制代码

否则为 nil

相关文章

  • https证书验证

    废话开篇:https 证书是什么?如何进行认证呢?带着这些疑问来简单的实现一下验证过程 简单的了解一下 https...

  • iOS https证书验证

    因为苹果审核原因项目需要添加证书验证,下面写下实现过程 1.拿到服务器颁布的证书,cer证书。我们服务器用的是腾讯...

  • HTTPS--证书验证

    HTTPS 默认工作在 TCP 协议443端口,它的工作流程一般如以下方式: 1、TCP 三次同步握手 2、客户端...

  • https证书验证不过

    在做https服务器的时候,在本机调试没有问题,代码放到另一台机器上不能正常工作。查找原因是客户端的证书的证书没有...

  • Alamofire https证书验证

    1、公钥验证 2、全验证

  • HTTPS实现原理

    参考自文章。 HTTPS实现原理 HTTPS分为证书验证和数据传输阶段: 证书验证阶段(非对称加密,公钥私钥) 1...

  • 面试题总结

    网络 AFNetwork实现 https证书的验证,为什么证书是安全的 https中ssl协议的过程 https证...

  • AFNetworking3.0安全策略<三>

    AFSecurityPolicy这个类的最用是为了验证HTTPS证书是否正确https=http+ssl证书 一 ...

  • iOS HTTPS自建证书验证

    前言 公司项目由HTTP转为HTTPS,需要对网络请求进行自建证书验证。主要是AFNetWorking、SDWeb...

  • https原理与证书验证

    https工作原理 浏览器验证 web端分两种情况,一是在地址栏输入https地址,这种情况浏览器会帮忙做证书的验...

网友评论

      本文标题:https证书验证

      本文链接:https://www.haomeiwen.com/subject/itxeertx.html