参考上文【OpenSSL】创建证书
openssl genrsa -out cakey.pem 2048
openssl req -new -key cakey.pem -subj "/CN=Example Root CA" -out cacsr.pem
openssl x509 -req -in cacsr.pem -signkey cakey.pem -days 999 -out cacert.pem
openssl genrsa -out alicekey.pem 2048
openssl req -new -key alicekey.pem -subj "/[email protected]" -out alicecsr.pem
openssl x509 -req -in alicecsr.pem -CA cacert.pem -CAkey cakey.pem -days 999 -set_serial 01 -out alicecert.pem
openssl pkcs12 -export -in alicecert.pem -inkey alicekey.pem <span style="font-family: Arial, Helvetica, sans-serif;">-certfile cacert.pem </span>-out alice.p12
openssl pkcs12 -in alice.p12 -nokeys -clcerts -out alicecert.pem
openssl pkcs12 -in alice.p12 -nocerts -out alicekey.pem
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).
-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; } }
/* 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选项可以设置显示名称,否则导入证书的时候,可能会显示一些乱码。