Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ssl/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何以编程方式在OpenSSL中加载PKCS#12文件?_C_Ssl_Openssl_Pkcs#12 - Fatal编程技术网

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

如何以编程方式在OpenSSL中加载PKCS#12文件?,c,ssl,openssl,pkcs#12,C,Ssl,Openssl,Pkcs#12,在基于OpenSSL的SSL服务器应用程序中,如何以编程方式加载PKCS#12文件 另外,我是否可以加载一个PKCS#12文件,该文件在OpenSSL中的同一文件中包含证书、密钥和CA?请尝试man SSL,该文件提供了OpenSSL函数的列表。类似于SSL\u load\u client\u CA\u file的东西可能适合您的需要;这取决于证书是在磁盘上的文件中还是已经在内存中。有很多辅助函数,其中一个可以实现这个功能。另外,请查看man PEM,了解PEM处理例程 编辑:嗯,也许结合使用d

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


另外,我是否可以加载一个PKCS#12文件,该文件在OpenSSL中的同一文件中包含证书、密钥和CA?

请尝试
man SSL
,该文件提供了OpenSSL函数的列表。类似于
SSL\u load\u client\u CA\u file
的东西可能适合您的需要;这取决于证书是在磁盘上的文件中还是已经在内存中。有很多辅助函数,其中一个可以实现这个功能。另外,请查看
man PEM
,了解PEM处理例程

编辑:嗯,也许结合使用
d2i_PKCS12_fp
PKCS12_parse
(均可从
)可以从文件中读取证书并对其进行解析。

是的,您可以使用OpenSSL在同一文件中加载包含证书、密钥和CA的PKCS 12文件

  • 使用
    d2i_PKCS12_fp()
    d2i_PKCS12_bio()
    加载PKCS#12文件
  • 可以选择使用
    PKCS12\u verify\u mac()
    验证密码
  • 使用
    PKCS12_parse()
    为您解密和提取密钥、证书和CA链
发件人:

#包括
#包括
#包括
#包括
#包括
/*简单PKCS#12文件读取器*/
int main(int argc,字符**argv)
{
文件*fp;
执行副总裁*PKEY;
X509*证书;
(X509)*ca的栈_=NULL;
PKCS12*p12;
int i;
如果(argc!=4){
fprintf(stderr,“用法:pkread p12文件密码opfile\n”);
出口(1);
}
OpenSSL_添加_所有算法();
错误加载加密字符串();
if(!(fp=fopen(argv[1],“rb”)){
fprintf(stderr,“打开文件%s\n时出错”,argv[1]);
出口(1);
}
p12=d2i_PKCS12_fp(fp,NULL);
fclose(fp);
如果(!p12){
fprintf(stderr,“读取PKCS#12文件时出错”);
错误打印错误fp(stderr);
出口(1);
}
if(!PKCS12_parse(p12,argv[2],&pkey,&cert,&ca)){
fprintf(stderr,“解析PKCS#12文件时出错\n”);
错误打印错误fp(stderr);
出口(1);
}
无PKCS12_(p12);
如果(!(fp=fopen(argv[3],“w”)){
fprintf(stderr,“打开文件%s\n时出错”,argv[1]);
出口(1);
}
如果(pkey){
fprintf(fp,***私钥***\n”);
PEM_write_PrivateKey(fp,pkey,NULL,NULL,0,NULL,NULL);
}
如果(证书){
fprintf(fp,***用户证书***\n”);
PEM_write_X509_AUX(fp,证书);
}
如果(ca和sk_X509_num(ca)){
fprintf(fp,***其他证书***\n”);
对于(i=0;i
请注意,代码会将证书作为可信证书(加密)写入。
如果您想要未加密的证书,请将对PEM_write_X509_AUX()的调用更改为PEM_write_X509()。

@Mathias您提供的上述代码用于读取DER编码P12证书。是否有任何API可以读取PEM编码的P12certificate@Balamurugan:我从未见过PEM编码的PKCS#12文件或支持它的软件。我想知道您是否可以扩展此答案,使其在不泄漏内存的情况下解析PKCS12结构(即,它适合在长时间运行的程序中使用)。特别是,PKCS12_parse似乎泄漏了大约4kB。@Jean-PaulCalderone:我添加了ca、cert和pkey的额外清理。我在OpenSSL 0.9.8中仍然存在漏洞,但在1.0.1中没有。该文本应该在注释中。这是我的问题,因为标记是BEGIN TRUSTED CERTIFICATE,而不是Just BEGIN CERTIFICATE
#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;
}