【问题标题】:How do you verify a public key was issued by your private CA?您如何验证公钥是由您的私有 CA 颁发的?
【发布时间】:2011-03-25 15:09:31
【问题描述】:

我创建了一个 CA 证书,并用它来颁发一个公钥。 在未来的某个日期,我需要验证加载的证书是否由我的 CA 颁发。

如何使用 OpenSSL API (c++) 做到这一点?

【问题讨论】:

    标签: c++ openssl


    【解决方案1】:

    openssl verify -CAfile <CA_cert_filename> <unknown_cert_filename> 命令会做你想做的事——试图找到能做你想做的事的 API 是很痛苦的,所以我建议找到 openssl verify 例程的源代码。

    (如果您可以选择实现,gnutls 看起来很有希望:

       #include <gnutls/x509.h>
    
       int gnutls_x509_crt_verify(gnutls_x509_crt_t cert, const  gnutls_x509_crt_t
       * CA_list, int CA_list_length, unsigned int flags, unsigned int * verify);
    

    但是 OpenSSL 到处都安装了..)

    【讨论】:

      【解决方案2】:

      我已将 verify.c(在 openssl/apps/ 中)减少到所需的最少功能。假设:cert 和 CA cert 都是 PEM 格式的文件。不需要 CRLS 或受信任的列表检查。

      使用您的证书和 CA PEM 文件的路径调用 verify()。

      static int verify(const char* certfile, const char* CAfile);
      static X509 *load_cert(const char *file);
      static int check(X509_STORE *ctx, const char *file);
      
      int verify(const char* certfile, const char* CAfile)
      {
          int ret=0;
          X509_STORE *cert_ctx=NULL;
          X509_LOOKUP *lookup=NULL;
      
          cert_ctx=X509_STORE_new();
          if (cert_ctx == NULL) goto end;
      
          OpenSSL_add_all_algorithms();
      
          lookup=X509_STORE_add_lookup(cert_ctx,X509_LOOKUP_file());
          if (lookup == NULL)
              goto end;
      
          if(!X509_LOOKUP_load_file(lookup,CAfile,X509_FILETYPE_PEM))
              goto end;
      
          lookup=X509_STORE_add_lookup(cert_ctx,X509_LOOKUP_hash_dir());
          if (lookup == NULL)
              goto end;
      
          X509_LOOKUP_add_dir(lookup,NULL,X509_FILETYPE_DEFAULT);
      
          ret = check(cert_ctx, certfile);
      end:
          if (cert_ctx != NULL) X509_STORE_free(cert_ctx);
      
          return ret;
      }
      
      static X509 *load_cert(const char *file)
      {
          X509 *x=NULL;
          BIO *cert;
      
          if ((cert=BIO_new(BIO_s_file())) == NULL)
              goto end;
      
          if (BIO_read_filename(cert,file) <= 0)
              goto end;
      
          x=PEM_read_bio_X509_AUX(cert,NULL, NULL, NULL);
      end:
          if (cert != NULL) BIO_free(cert);
          return(x);
      }
      
      static int check(X509_STORE *ctx, const char *file)
      {
          X509 *x=NULL;
          int i=0,ret=0;
          X509_STORE_CTX *csc;
      
          x = load_cert(file);
          if (x == NULL)
              goto end;
      
          csc = X509_STORE_CTX_new();
          if (csc == NULL)
              goto end;
          X509_STORE_set_flags(ctx, 0);
          if(!X509_STORE_CTX_init(csc,ctx,x,0))
              goto end;
          i=X509_verify_cert(csc);
          X509_STORE_CTX_free(csc);
      
          ret=0;
      end:
          ret = (i > 0);
          if (x != NULL)
              X509_free(x);
      
          return(ret);
      }
      

      【讨论】:

      • 你能用cmets解释一下代码吗?我无法理解这个验证过程的逻辑
      • 可以用内存代替文件吗?我想让 A 向 B 发送证书,并进行验证。有人愿意分享代码吗?非常感谢。
      • user180574 - 我认为你需要使用 BIO_new_mem_buf
      • 您不需要调用 X509_STORE_add_lookup(... X509_LOOKUP_hash_dir());X509_LOOKUP_add_dir(NULL, ...);,因为您提供了 CA 文件。
      • 您可以在X509_STORE_set_flags(ctx, 0); 的上下文中添加标志。 X509_V_FLAG_X509_STRICT | X509_V_FLAG_CHECK_SS_SIGNATURE | X509_V_FLAG_POLICY_CHECK 可能是不错的选择。一定要远离X509_V_FLAG_ALLOW_PROXY_CERTS
      猜你喜欢
      • 2021-03-23
      • 1970-01-01
      • 2012-03-19
      • 2017-10-19
      • 1970-01-01
      • 1970-01-01
      • 2016-01-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多