壮志,敢教日月换新天。为有牺牲多

CocoaHttpServer设置https

热烈欢迎,请直接点击!!!

进入博主App Store主页,下载使用各个作品!!!

注:博主将坚持每月上线一个新app!!!

客户端向服务器发起需求 ,服务器把证书发给客户端,客户端验证下证书是否合法,然后用证书的数据加密传输数据给服务器,服务器解密

使用 OpenSSL 生成自签名证书

上次更新时间: 2021-07-08

OpenSSL 是 SSL 和 TLS 协议的开放式源代码实现。它在标准通信层上提供了传输层安全性,允许其与诸多网络应用程序和服务相结合。

开始之前

需要以下某个角色才能完成此任务:

  • 管理员
  • 所有者
  • 拓扑管理员
  • 具有 Settings:Manage 许可权的定制角色

关于此任务

本主题告知您如何使用 OpenSSL 工具箱生成自签名 SSL 证书以启用 HTTPS 连接。

过程

要使用 OpenSSL 生成自签名 SSL 证书,请完成以下步骤:

  1. 写下您的 SSL 证书的公共名称 (CN)。 该公共名称 (CN) 是使用该证书的系统的标准名称。 对于静态 DNS,请使用网关集群中设置的主机名或 IP 地址(例如,192.16.183.131 或 dp1.acme.com)。
  2. 运行以下 OpenSSL 命令来生成您的专用密钥和公共证书。回答问题并在出现提示时输入公共名称。
    openssl req -newkey rsa:2048 -nodes -keyout key.pem -x509 -days 365 -out certificate.pem
  3. 检查已创建的证书:
    openssl x509 -text -noout -in certificate.pem
  4. 将密钥和证书组合在 PKCS#12 (P12) 捆绑软件中:
    openssl pkcs12 -inkey key.pem -in certificate.pem -export -out certificate.p12
  5. 验证您的 P12 文件。
    openssl pkcs12 -in certificate.p12 -noout -info
    创建证书文件后,即可将其上载至密钥库。
  6. 在 云管理器 中,单击 资源 资源。
  7. 选择 TLS。
  8. 单击“密钥库”表中的创建。
  9. 遵循创建密钥库中的指示信息创建密钥库并上载证书文件。
    注:
    • API Connect 仅支持按 P12 (PKCS12) 格式文件提供证书。
    • P12 文件必须包含专用密钥、来自认证中心的公共证书,以及用于签名的所有中间证书。
    • P12 文件最多可包含 10 个中间证书。
  10. 单击保存。

——————————————————————————————————————————

其他方法的生成证书步骤

复制代码
// 第一步,为服务器端和客户端准备公钥、私钥
# 生成服务器端私钥
openssl genrsa -out server.key 1024
# 生成服务器端公钥
openssl rsa -in server.key -pubout -out server.pem

// 第二步,生成 CA 证书
# 生成 CA 私钥
openssl genrsa -out ca.key 1024
openssl rsa -in ca.key -pubout -out ca.pem
# X.509 Certificate Signing Request (CSR) Management.
openssl req -new -key ca.key -out ca.csr
# X.509 Certificate Data Management.
openssl x509 -req -in ca.csr -signkey ca.key -out ca.crt

// 第三步,生成服务器端证书
# 服务器端需要向 CA 机构申请签名证书,在申请签名证书之前依然是创建自己的 CSR 文件
openssl req -new -key server.key -out server.csr
# 向自己的 CA 机构申请证书,签名过程需要 CA 的证书和私钥参与,最终颁发一个带有 CA 签名的证书
openssl x509 -req -CA ca.crt -CAkey ca.key -CAcreateserial -in server.csr -out server.crt

// 第四步,生成cer文件
# 使用openssl 进行转换
openssl x509 -in server.crt -out server.cer -outform der
openssl x509 -in ca.crt -out ca.cer -outform der

// 将证书导出成浏览器支持的.p12格式,记得导出密码
openssl pkcs12 -export -clcerts -in server.pem -inkey server.key -out server.p12
复制代码

在第二步时会出来一个填写资料的界面:

Country Name (2 letter code) [AU]:CN
State or Province Name (full name) [Some-State]:Guangdong
Locality Name (eg, city) []:Shenzhen
Organization Name (eg, company) [Internet Widgits Pty Ltd]:cnblogs
Organizational Unit Name (eg, section) []:strengthen
Common Name (e.g. server FQDN or YOUR name) []:localhost
Email Address []:newsagency@163.com

配置服务器

为了方便,我是以mac本地电脑做服务器,使用的是XAMPP搭建的服务器使用的是apache。在其他服务器上应该就是文件路径位置不一样,其他应该是一样的。如果有些服务器没开启ssl,可以网上搜索怎么开启。

修改httpd-ssl.conf文件 把server.crt和server.key的路径修改对就好了
SSLCertificateFile /apache/conf/server.crt  
SSLCertificateKeyFile /apache/conf/server.key 

文件里设置一下开启 https 功能:

复制代码
 
- (BOOL)isSecureServer
{
 
    // Create an HTTPS server (all connections will be secured via SSL/TLS)
    return YES;
}
 
/**
 * This method is expected to returns an array appropriate for use in kCFStreamSSLCertificates SSL Settings.
 * It should be an array of SecCertificateRefs except for the first element in the array, which is a SecIdentityRef.
 **/
- (NSArray *)sslIdentityAndCertificates
{
    SecIdentityRef identityRef = NULL;
    SecCertificateRef certificateRef = NULL;
    SecTrustRef trustRef = NULL;
 
    NSString *thePath = [[NSBundle mainBundle] pathForResource:@"my" ofType:@"p12"];
    NSData *PKCS12Data = [[NSData alloc] initWithContentsOfFile:thePath];
    CFDataRef inPKCS12Data = (CFDataRef)CFBridgingRetain(PKCS12Data);
    CFStringRef password = CFSTR("123");
    const void *keys[] = { kSecImportExportPassphrase };
    const void *values[] = { password };
    CFDictionaryRef optionsDictionary = CFDictionaryCreate(NULL, keys, values, 1, NULL, NULL);
    CFArrayRef items = CFArrayCreate(NULL, 0, 0, NULL);
 
    OSStatus securityError = errSecSuccess;
    securityError =  SecPKCS12Import(inPKCS12Data, optionsDictionary, &items);
    if (securityError == 0) {
        CFDictionaryRef myIdentityAndTrust = CFArrayGetValueAtIndex (items, 0);
        const void *tempIdentity = NULL;
        tempIdentity = CFDictionaryGetValue (myIdentityAndTrust, kSecImportItemIdentity);
        identityRef = (SecIdentityRef)tempIdentity;
        const void *tempTrust = NULL;
        tempTrust = CFDictionaryGetValue (myIdentityAndTrust, kSecImportItemTrust);
        trustRef = (SecTrustRef)tempTrust;
    } else {
        NSLog(@"Failed with error code %d",(int)securityError);
        return nil;
    }
 
    SecIdentityCopyCertificate(identityRef, &certificateRef);
    NSArray *result = [[NSArray alloc] initWithObjects:(id)CFBridgingRelease(identityRef),   (id)CFBridgingRelease(certificateRef), nil];
 
    return result;
}
复制代码

总结一下配置过程中可能碰到配置完成后还是无法访问https的问题:

1、可以判断p12文件是否导入项目,以及路径是否寻找正确

2、确保iOS项目中代码所有的请求都为https请求,因为ssl配置服务器的时候,如果服务器中含有http请求,同样会出现不安全的ssl情况

3、在GCDAsyncSocket.m文件中注释该段代码

//    if (value)
//    {
//        NSAssert(NO, @"Security option unavailable - kCFStreamSSLLevel"
//                     @" - You must use GCDAsyncSocketSSLProtocolVersionMin & GCDAsyncSocketSSLProtocolVersionMax");
//
//        [self closeWithError:[self otherError:@"Security option unavailable - kCFStreamSSLLevel"]];
//        return;
//    }

配置AFNetworking

复制代码
+ (AFSecurityPolicy*)customSecurityPolicy
{
    // /先导入证书
    NSString *cerPath = [[NSBundle mainBundle] pathForResource:@"server" ofType:@"cer"];//证书的路径
    NSData *certData = [NSData dataWithContentsOfFile:cerPath];

    // AFSSLPinningModeCertificate 使用证书验证模式
    AFSecurityPolicy *securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate];

    // allowInvalidCertificates 是否允许无效证书(也就是自建的证书),默认为NO
    // 如果是需要验证自建证书,需要设置为YES
    securityPolicy.allowInvalidCertificates = YES;

    //validatesDomainName 是否需要验证域名,默认为YES;
    //假如证书的域名与你请求的域名不一致,需把该项设置为NO;如设成NO的话,即服务器使用其他可信任机构颁发的证书,也可以建立连接,这个非常危险,建议打开。
    //置为NO,主要用于这种情况:客户端请求的是子域名,而证书上的是另外一个域名。因为SSL证书上的域名是独立的,假如证书上注册的域名是www.google.com,那么mail.google.com是无法验证通过的;当然,有钱可以注册通配符的域名*.google.com,但这个还是比较贵的。
   //如置为NO,建议自己添加对应域名的校验逻辑。
    securityPolicy.validatesDomainName = NO;

    securityPolicy.pinnedCertificates = @[certData];

    return securityPolicy;
}

+ (void)post:(NSString *)url params:(NSDictionary *)params success:(void (^)(id))success failure:(void (^)(NSError *))failure
{
    // 1.获得请求管理者
    AFHTTPSessionManager *mgr = [AFHTTPSessionManager manager];
    // 2.申明返回的结果是text/html类型
    mgr.responseSerializer = [AFHTTPResponseSerializer serializer];

    // 加上这行代码,https ssl 验证。
    [mgr setSecurityPolicy:[NetworkHelpManager customSecurityPolicy]];

    // 3.发送POST请求
    [mgr POST:url parameters:params
  success:^(NSURLSessionDataTask *operation, id responseObj) {
          if (success) {
            success(responseObj);
         }
      } failure:^(NSURLSessionDataTask *operation, NSError *error) {
          if (failure) {
              failure(error);
          }
      }];
}
复制代码

info.plist,配置白名单

复制代码
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <false/>
    <key>NSExceptionDomains</key>
    <dict>
        <key>cer文件中查看</key>
        <dict>
            <key>NSExceptionAllowsInsecureHTTPLoads</key>
            <true/>
            <key>NSExceptionMinimumTLSVersion</key>
            <string>TLSv1.0</string>
            <key>NSExceptionRequiresForwardSecrecy</key>
            <false/>
            <key>NSIncludesSubdomains</key>
            <true/>
        </dict>
    </dict>
</dict>
复制代码

 

posted @   为敢技术  阅读(347)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
历史上的今天:
2019-04-02 [CocoaPods]客户端加载第三方库
2019-04-02 [CocoaPods]终端方式加载第三方库
2019-04-02 [CocoaPods]CocoaPods安装详解
2019-04-02 [Swift]LeetCode269. 外星人词典 $ Alien Dictionary
2019-04-02 [Mac]如何让两个窗口各占半个屏幕
点击右上角即可分享
微信分享提示