如何以编程方式在OpenSSL中加载PKCS#12文件?
在基于OpenSSL的SSL服务器应用程序中,如何以编程方式加载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
另外,我是否可以加载一个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()
加载PKCS#12文件d2i_PKCS12_bio()
- 可以选择使用
验证密码PKCS12\u verify\u mac()
- 使用
为您解密和提取密钥、证书和CA链PKCS12_parse()
#包括
#包括
#包括
#包括
#包括
/*简单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;
}