• 使用 Openssl 验证自签名证书


    iOS的 security framework 框架前面已经介绍。这个框架提供有限的功能,使用它能做到的,比你想象的要少。笔者一直想找一个 iOS 下比较好的功能全面的安全算法库,结果却一无所获。不知道谁能介绍下这方面。

    最终还是只有求助于闻名已久的 Openssl library。

    Openssl 确实十分强大,然而其糟糕文档仍让人难以满意。当然,网络上使用Openssl 的例子非常多,不过能写这个的似乎都是高手,必然跟菜鸟划清界限——如果你是一个菜鸟,高手是不会跟你解释每行代码分别都是什么意思。坚信求人不如求己,钻研了许久,终于写出了点能够运行的 Code。

    主要参考的来源:一是 Openssl 库中的源代码,一是这本书《Openssl编程》(赵春平 著)——说它是书可能有些勉强,因为没有得以出版(不知道出版社的编辑们看到这本书没?)。但它确实是本 Openssl 方面比较全面的介绍(难得的中文参考书),如果你想对 Openssl 有所了解,不妨把它找来看看(openssl.cn 论坛上)。

    一、编译 iOS Openssl 静态库

    请参考《在你的 iOS App 中使用 OpenSSL 库》。

    二、在 Xcode 项目中进行设置

    同上

    三、使用 Openssl 验证

    直接上代码:

    #import <OpenSsl/x509.h>

    #import <Openssl/x509v3.h>

    void loadCert( NSString *, X509 *);

    void printX509( X509 *);

    void verity( X509 *, NSString *);

    int main( int argc, char *argv[]) {

        NSAutoreleasePool * pool = [[ NSAutoreleasePool alloc ] init ];

    NSString *file= @"/Users/username/Desktop/client.cer" ;

    // 新建一个 x509 结构

    X509 *x= X509_new ();

    loadCert (file,x);

    printX509 (x);

    // 开始验证

    verity (x,file);

    // 释放结构体

    X509_free (x);

    [pool release ];

        return 0 ;

    }

    // 加载证书到 X509 结构

    void loadCert( NSString * string, X509 * x){

    NSData * certData;

    unsigned char buf[ 4096 ],*p;

    int len;

    assert (string!= nil );

    // 读取证书文件

    certData=[ NSData dataWithContentsOfFile :string];

    assert (certData!= nil );

    len=certData. length ;

    // NSData-->uchar*

    [certData getBytes :( void *)buf length :len];

    // p-->buf[0]

    p=buf;

     

    // buf 中的数据进行解码,并返回一个 X509 结构

    d2i_X509 (&x,( const unsigned char **)&p,len);

    }

    // 打印 X509 结构

    void printX509( X509 * x){

    int ret;

    BIO *b;

    // 初始化一个文件 BIO

    b= BIO_new ( BIO_s_file ());

    // 把标准输出 stdout 指向这个文件 BIO

    BIO_set_fp (b, stdout , BIO_NOCLOSE );

    // X509 结构打印输出到文件 BIO

    ret= X509_print (b,x);

    // 释放流

    BIO_free (b);

    }

    // 验证自签名证书

    void verity( X509 * x1, NSString * string){

    int i= 0 ;

    X509_LOOKUP *lookup= NULL ;

    // 证书 store 结构体

    X509_STORE *cert_ctx;

    // 证书 store 相关的上下文

    X509_STORE_CTX *csc;

    // 构造 CA X509_STORE 结构体,包含所有有效证书链和废止证书链,用于校验

    cert_ctx= X509_STORE_new ();

    // store 中加入一个搜索,可以查找单个的文件

    lookup= X509_STORE_add_lookup (cert_ctx, X509_LOOKUP_file ());

    assert (lookup!= NULL );

    // 通过 lookup 加载 client.cer 内的证书(自签名)

    i= X509_LOOKUP_load_file (lookup,[string UTF8String ], X509_FILETYPE_ASN1 );

    assert (i!= 0 );

    // flags 赋值给 ctx 里面的 flags, 表明了验证证书时需要验证哪些项

    // flags 可以是:

    // X509_V_FLAG_IGNORE_CRITICAL

    // X509_V_FLAG_CB_ISSUER_CHECK

    // X509_V_FLAG_CRL_CHECK

    // X509_V_FLAG_CRL_CHECK│X509_V_FLAG_CRL_CHECK_ALL

    X509_STORE_set_flags (cert_ctx, X509_V_FLAG_CRL_CHECK_ALL );

    csc = X509_STORE_CTX_new ();

    if (! X509_STORE_CTX_init (csc,cert_ctx ,x1, NULL ))

    {

    NSLog ( @"Can NOT ctx init" );

    return ;

    }

    // 开始校验

    i= 0 ;

    i= X509_verify_cert (csc);

    X509_STORE_CTX_free (csc);

    if (i)

    NSLog ( @"cert OK" );

    else

    {

    NSLog ( @"cert error" );

    }

    }

     

    先搞个有效证书,client.cer,放在你的桌面上。运行程序,控制台打印:

    cert OK

    如果证书失效了(比如把证书有效期改为无效),控制台则打印:

    cert error

     

  • 相关阅读:
    android基础开发之scrollview
    java网络---再论URL & URI
    Android Studio 有用的插件
    java网络---查找Internet
    java网络---流
    Qt学习之路(1)------Qt常用类用法说明
    将批量下载的博客导入到手机后,通过豆约翰博客阅读器APP(Android手机)进行浏览,白字黑底,保护眼睛,图文并茂。
    如何收藏互联网上的任意网页到系统某个分类下,之后进行批量导出发布等---博客备份专家的博文收藏功能您不可不知
    很喜欢看某方面的文章,如何将不同站点,不同博主同一类别的文章归类整合到一起,再批量导出成各种格式---豆约翰博客备份专家新增按分类收藏博文功能
    豆约翰博客备份专家博客导出示例(PDF,CHM)
  • 原文地址:https://www.cnblogs.com/encounter/p/2188478.html
Copyright © 2020-2023  润新知