【OpenSSL】使用证书和私钥导出P12格式个人证书

参考上文【OpenSSL】创建证书


1, 产生CA证书


1.1, 生成ca的私钥

openssl genrsa -out cakey.pem 2048


1.2, 生成ca的自签名证书请求

openssl req -new -key cakey.pem -subj "/CN=Example Root CA" -out cacsr.pem 


1.3, 自签名ca的证书

openssl x509 -req -in cacsr.pem -signkey cakey.pem -days 999 -out cacert.pem


2, 产生个人证书


2.1, 生成个人证书的私钥

openssl genrsa -out alicekey.pem 2048


2.2, 生成个人证书请求

openssl req -new -key alicekey.pem -subj "/emailAddress=alice@example.com" -out alicecsr.pem


2.3, 签发个人证书

openssl x509 -req -in alicecsr.pem -CA cacert.pem -CAkey cakey.pem -days 999 -set_serial 01 -out alicecert.pem



3, 合并证书和私钥得到p12格式的个人证书


openssl pkcs12 -export -in alicecert.pem -inkey alicekey.pem -certfile cacert.pem -out alice.p12 

4, 提取个人证书

openssl pkcs12 -in alice.p12 -nokeys -clcerts -out alicecert.pem


5, 提取个人证书的私钥

openssl pkcs12 -in alice.p12 -nocerts -out alicekey.pem


6, 提取ca证书

openssl pkcs12 -in alice.p12 -nokeys -cacerts -out cacert.pem



备注:

1,绑定ca证书的时候,-certfile和-CAfile的区别 http://arstechnica.com/civis/viewtopic.php?p=24680099

You're right, the documentation is confusing (man page here*), but I think I've figured it out, after some testing:
-certfile adds all certificates in that file to the .p12 store (in addition to the input certificate).
-CAfile and -CApath are used to build the "standard CA store" (just as they do for openssl s_client), which is only used with the -chain option, which will add the entire certification chain for the input certificate to the .p12, assuming it can be found in that file and/or directory. Without the -chain option they do nothing.

* Also, most distros supply man pages for the openssl subcommands under the subcommand name, e.g. pkcs(1).

see

http://openssl.6102.n7.nabble.com/How-to-include-intermediate-in-pkcs12-td49603.html
A lot of things on the Internet are wrong. The OpenSSL man page does not say multiple
occurrences work and I’m pretty sure it never did, nor did the code. In general
OpenSSL commandlines don’t handle repeated options; the few exceptions are noted.
pkcs12 -caname (NOT –cafile) IS one of the few that can be repeated, and possibly
some things on the Internet got that confused. However, the commandlines (at least
usually?) don’t *diagnose* repeated (and overridden) options.

pkcs12 –export gets certs from up to three places:
- the input file (-in if specified else stdin redirected or piped)
- -certfile if specified (once, as you saw)
- the truststore if –CAfile and/or –CApath specified IF NEEDED
 
In other words, any cert in infile or certfile is always in the output, needed or not.
If that set does not provide a complete chain, pkcs12 will try to complete it using
the truststore if specified, but will produce output even if it remains incomplete.
Like other commandlines, and many programs using the library, the truststore
can be a single file with –CAfile (NOT –cafile) or a directory of hashnamed
links or files with –CApath or both.

If the cert you are putting in pkcs12 is under a CA that you trust other peers to use
and thus you have in your truststore, easiest to use it from there. Similarly if your cert
is under an intermediate (or several) that you have in your truststore to allow peers
to use even if the peers don’t send (as they should), easiest to use from there.
Otherwise IMO it’s easiest to just put in infile or –certfile (or a combination),
although the option of temporarily creating or modifying a truststore works.
 
Whether to do your trustore with CAfile or CApath or both is a more general question
and depends partly on whether you use somebody’s package.
For example the curl website supplies the Mozilla truststore in CAfile format;
when I want to use that I don’t bother converting to CApath format.
 
From: [hidden email] [[hidden email]] On Behalf Of Edward Ned Harvey (openssl)
Sent: Tuesday, April 22, 2014 15:31
To: [hidden email]
Subject: *** Spam *** How to include intermediate in pkcs12?

A bunch of things on the internet say to do "-cafile intermediate.pem -cafile root.pem" or "-certfile intermediate.pem -certfile root.pem" and they explicitly say that calling these command-line options more than once is ok and will result in both the certs being included in the final pkcs12...  But I have found this to be untrue.
I have found, that if I concatenate intermediate & root into a single glom file, and then I specify -certfile once for the glom, then my pfx file will include the complete chain.  But if I use -certfile twice, I get no intermediate in my pfx.  And I just wasted more time than I care to describe, figuring this out.
So...  While concatenation/glom is a viable workaround, I'd like to know, what's supposed to work?  And was it a new feature introduced after a certain rev or something?   I have OpenSSL 0.9.8y command-line on Mac OSX, and OpenSSL 1.0.1e command-line on cygwin.  I believe I've seen the same behavior in both.


-CAfile 的处理逻辑

        /* If chaining get chain from user cert */
        if (chain) {
            int vret;
            STACK_OF(X509) *chain2;
            X509_STORE *store = X509_STORE_new();
            if (!store) {
                BIO_printf(bio_err, "Memory allocation error\n");
                goto export_end;
            }
            if (!X509_STORE_load_locations(store, CAfile, CApath))
                X509_STORE_set_default_paths(store);

            vret = get_cert_chain(ucert, store, &chain2);
            X509_STORE_free(store);

            if (!vret) {
                /* Exclude verified certificate */
                for (i = 1; i < sk_X509_num(chain2); i++)
                    sk_X509_push(certs, sk_X509_value(chain2, i));
                /* Free first certificate */
                X509_free(sk_X509_value(chain2, 0));
                sk_X509_free(chain2);
            } else {
                if (vret >= 0)
                    BIO_printf(bio_err, "Error %s getting chain.\n",
                               X509_verify_cert_error_string(vret));
                else
                    ERR_print_errors(bio_err);
                goto export_end;
            }
        }

-certfile的处理逻辑

        /* Add any more certificates asked for */
        if (certfile) {
            STACK_OF(X509) *morecerts = NULL;
            if (!(morecerts = load_certs(bio_err, certfile, FORMAT_PEM,
                                         NULL, e,
                                         "certificates from certfile")))
                goto export_end;
            while (sk_X509_num(morecerts) > 0)
                sk_X509_push(certs, sk_X509_shift(morecerts));
            sk_X509_free(morecerts);
        }


2,-name选项可以设置显示名称,否则导入证书的时候,可能会显示一些乱码。


  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值