如何以编程方式在OpenSSL中加载PKCS#12文件?

时间:2011-06-16 12:27:19

标签: c ssl openssl pkcs#12

在基于OpenSSL的SSL服务器应用程序中,我们如何以编程方式加载PKCS#12文件?

另外,我可以加载具有证书,密钥和密钥的PKCS#12文件吗? CA在OpenSSL中的同一个文件中?

3 个答案:

答案 0 :(得分:37)

是的,您可以使用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;
}

答案 1 :(得分:1)

试试man SSL,它会为您提供OpenSSL功能列表。 SSL_load_client_CA_file之类的东西可能适合您的需求;这取决于证书是在磁盘上的文件中还是已在内存中。有很多辅助函数,其中一个可以解决问题。另请查看man PEM以了解PEM处理例程。

编辑:嗯,可能是d2i_PKCS12_fpPKCS12_parse的组合(两者都来自<openssl/pkcs12.h>),您可以从文件中读取证书并解析它。

答案 2 :(得分:1)

警告代码将证书写为可信证书(加密)。 如果您需要未加密的证书,请将对PEM_write_X509_AUX()的调用更改为PEM_write_X509()。