【发布时间】:2011-09-16 08:07:40
【问题描述】:
在基于 OpenSSL 的 SSL 服务器应用程序中,我们如何以编程方式加载 PKCS#12 文件?
另外,我可以在 OpenSSL 的同一文件中加载具有证书、密钥和 CA 的 PKCS#12 文件吗?
【问题讨论】:
在基于 OpenSSL 的 SSL 服务器应用程序中,我们如何以编程方式加载 PKCS#12 文件?
另外,我可以在 OpenSSL 的同一文件中加载具有证书、密钥和 CA 的 PKCS#12 文件吗?
【问题讨论】:
试试man SSL,它会为您提供 OpenSSL 函数列表。 SSL_load_client_CA_file 之类的东西可能适合您的需求;这取决于证书是在磁盘上的文件中还是已经在内存中。有很多辅助函数,其中一个可以解决问题。另请查看man PEM 了解 PEM 处理例程。
编辑:嗯,也许d2i_PKCS12_fp 和PKCS12_parse 的组合(两者都可从<openssl/pkcs12.h> 获得)让您从文件中读取证书并解析它。
【讨论】:
是的,您可以使用 OpenSSL 在同一个文件中加载包含证书、密钥和 CA 的 PKCS#12 文件。
d2i_PKCS12_fp() 或d2i_PKCS12_bio() 加载PKCS#12 文件。PKCS12_verify_mac() 来验证密码。PKCS12_parse() 为您解密和提取密钥、证书和CA 链。来自openssl-1.0.0d/demos/pkcs12/pkread.c:
#include <stdio.h>
#include <stdlib.h>
#include <openssl/pem.h>
#include <openssl/err.h>
#include <openssl/pkcs12.h>
/* Simple PKCS#12 file reader */
int main(int argc, char **argv)
{
FILE *fp;
EVP_PKEY *pkey;
X509 *cert;
STACK_OF(X509) *ca = NULL;
PKCS12 *p12;
int i;
if (argc != 4) {
fprintf(stderr, "Usage: pkread p12file password opfile\n");
exit (1);
}
OpenSSL_add_all_algorithms();
ERR_load_crypto_strings();
if (!(fp = fopen(argv[1], "rb"))) {
fprintf(stderr, "Error opening file %s\n", argv[1]);
exit(1);
}
p12 = d2i_PKCS12_fp(fp, NULL);
fclose (fp);
if (!p12) {
fprintf(stderr, "Error reading PKCS#12 file\n");
ERR_print_errors_fp(stderr);
exit (1);
}
if (!PKCS12_parse(p12, argv[2], &pkey, &cert, &ca)) {
fprintf(stderr, "Error parsing PKCS#12 file\n");
ERR_print_errors_fp(stderr);
exit (1);
}
PKCS12_free(p12);
if (!(fp = fopen(argv[3], "w"))) {
fprintf(stderr, "Error opening file %s\n", argv[1]);
exit(1);
}
if (pkey) {
fprintf(fp, "***Private Key***\n");
PEM_write_PrivateKey(fp, pkey, NULL, NULL, 0, NULL, NULL);
}
if (cert) {
fprintf(fp, "***User Certificate***\n");
PEM_write_X509_AUX(fp, cert);
}
if (ca && sk_X509_num(ca)) {
fprintf(fp, "***Other Certificates***\n");
for (i = 0; i < sk_X509_num(ca); i++)
PEM_write_X509_AUX(fp, sk_X509_value(ca, i));
}
sk_X509_pop_free(ca, X509_free);
X509_free(cert);
EVP_PKEY_free(pkey);
fclose(fp);
return 0;
}
【讨论】:
请注意,代码会将证书作为可信证书(加密)写出。 如果您想要未加密的证书,请将对 PEM_write_X509_AUX() 的调用更改为 PEM_write_X509()。
【讨论】: