iOS 公钥获取 公钥验签 证书验签 - Go语言中文社区

iOS 公钥获取 公钥验签 证书验签


上一篇博客有点儿乱,到最后把自己都快绕晕了。那么现在我还是简单讲一下快速入门的证书验签过程吧,尽量保准新人直接复制粘贴代码就可以实现功能,以实现效率最大化。

1.证书验证书

第一步加载证书
如果你的证书是cer格式用下面的代码

// 加载证书到 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);
}

如果你的证书是pem格式使用这种加载当然你也可以选择把两种格式合并在一起

X509 *loadMyPem(char *filePath)
{
    X509 *x;
    FILE *fp;
    if ((fp = fopen(filePath, "r")) == NULL) {
        return NULL;
    }
    x = PEM_read_X509(fp, NULL, NULL, NULL);

    X509_print_fp(stdout, x);
    X509_NAME   *subject   =   X509_get_subject_name(x);
    printf("%lun", X509_get_version(x));
    printf("%lun", X509_subject_name_hash(x));
    printf("%lun", X509_issuer_name_hash(x));

    BIO_free(b);
    return x;
}

好了骚年,可以去验证了

// 验证证书
int verity(){

    OpenSSL_add_all_algorithms();
    int ret= 0 ;
    NSString *userFile = [[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent:@"User.pem"];
    NSString *rootFile = [[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent:@"Root.pem"];

    /**
    //加载cer证书
    X509 *user= X509_new ();
    loadCert (userFile,user);

    */
    //加载pem证书
    X509 *user = loadMyPem([userFile UTF8String]);

    /**共钥验证证书
    //加载cer证书
    X509 *ca= X509_new ();
    loadCert (rootFile,ca);
    //加载pem证书
    X509 *ca = loadMyPem([rootFile UTF8String]);

    EVP_PKEY *public_key = X509_extract_key(ca);
    int isSuccess = X509_verify(user, public_key);
    NSLog(@"%@*********%d",[NSDate date],isSuccess);
    */
    // 证书 store 结构体
    X509_STORE *cert_ctx;
    // 证书 store 相关的上下文
    X509_STORE_CTX *ctx;
    // 构造 CA 的 X509_STORE 结构体,包含所有有效证书链和废止证书链,用于校验
    cert_ctx= X509_STORE_new ();
    ctx = X509_STORE_CTX_new();
    X509_STORE_set_verify_cb(cert_ctx, cb);
    ERR_load_crypto_strings();

    X509_LOOKUP *lookup= NULL ;
    // 往 store 中加入一个搜索,可以查找单个的文件
    lookup= X509_STORE_add_lookup (cert_ctx, X509_LOOKUP_file ());
    assert (lookup!= NULL );
    // 通过 lookup 加载根证书
    //TODO:证书格式动态变化
    ret= X509_LOOKUP_load_file (lookup,[rootFile UTF8String ], X509_FILETYPE_PEM );
    assert (ret != 0 );

//    X509_STORE_set_flags(ca_store,X509_V_FLAG_EXTENDED_CRL_SUPPORT);

    ret = X509_STORE_CTX_init(ctx, cert_ctx, user, NULL);
    if ( ret != 1 )
    {
        fprintf(stderr, "X509_STORE_CTX_init fail, ret = %dn", ret);
        goto EXIT;
    }

    //openssl-1.0.1c/crypto/x509/x509_vfy.h
    ret = X509_verify_cert(ctx);
//    X509_verify(<#X509 *a#>, <#EVP_PKEY *r#>)
    if ( ret != 1 )
    {
        fprintf(stderr, "X509_verify_cert fail, ret = %d, error id = %d, %sn",
                ret, ctx->error, X509_verify_cert_error_string(ctx->error));
        goto EXIT;
    }
EXIT:
    X509_free(user);
//    X509_free(ca);

    X509_STORE_CTX_cleanup(ctx);
    X509_STORE_CTX_free(ctx);

    X509_STORE_free(cert_ctx);

    return ret == 1 ? 0 : -1;
}

完。是不是很简单?最后有木有很欣喜的看到OK!是不是很简单?但是一定要注意的是,OpenSSL_add_all_algorithms();这行代码一定不能少。不然会直接报错error id = 7, certificate signature failure,有人说这是缺少跟证书的问题但是我确实加进去了,因为add根证书的时候并没有报错。如果当你在X509_STORE_CTX_init之前设置X509_STORE_set_flags (cert_ctx, X509_V_FLAG_USE_CHECK_TIME );控制台会提示error id = 9, certificate is not yet valid。无论你检查电脑时间、证书时间、手机时间都会发现时间都是对的。而且当你通过控制台openssl指令验证两个证书时也是对的。
这里写图片描述
所以这种情况请一定注意在初始化的时候加OpenSSL_add_all_algorithms();打开底层签名算法,当然如果你是自己实现了算法那就无所谓了。

2.共钥验证书
哈哈,其实上面的证书验证书中已经给出代码了,解注释就好了!

最后给一个从pem提取共钥的指令

openssl x509 -in /Users/XXXX/Desktop/Root.pem -pubkey

其实上面那个从证书中读取共钥的方法有时候不太适合,所以我们必须知道怎么把这个提取出来的共钥封装出来

EVP_PKEY *generatePublicKey()
{
    const char *public_key = "-----BEGIN PUBLIC KEY-----n"
    "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwC5O7yx5L57RNv5dIBZdn"
    "aVI+ccBgj2JiUiTuyWp8GuurAnjNnGrBd3ve7OPLQGHaPnYT0MLOdoFJ0HTvCrwwn"
    "IdWAquebAusGSySwvZgrMR2nzWMkEAyJMOJeX/T9yN0rmZtOBts8Vjw8zLrbF4z1n"
    "gpqYiCgfWXNpwbMr2GWNLBWRFvckTOqsusCPMG659IpD+4jps8jcBzjbYd/5AC1Jn"
    "2BAq0rU3yC7fCP78/P5kIGSCiLJ7PcjHOWtif5J9KXyOGFFz8ryS6BRRIPtXnDcun"
    "6KH/3k0SI1ggJFa6CgMic6Pr6FbOcj9B4pn7fnGK5D4aGk/HihEODCukpvJFA6DWn"
    "QwIDAQAB"
    "n-----END PUBLIC KEY-----n";

    BIO *bp = BIO_new_mem_buf(public_key, -1);
    EVP_PKEY *p_key;

    if (bp == NULL) {
        NSLog(@"generate_key bio file new error!n");
        return NULL;
    }

    p_key = PEM_read_bio_PUBKEY(bp, NULL, NULL, NULL);

    return p_key;
}

剧终!

版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/longlongvalue/article/details/77721110
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
  • 发表于 2020-03-01 21:48:21
  • 阅读 ( 1478 )
  • 分类:

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢