• OpenSSL 使用拾遗(一)---- 生成 pkcs12 文件


    从本期开始,记录一些在使用 OpenSSL 过程中碰到的问题及解决办法

    在 Linux 下需要生成 pkcs12 文件,立即想到 OpenSSL。键入如下命令

    ~ # openssl pkcs12 -export -inkey clientkey.pem -in client.crt -out client.p12
    No certificate matches private key
    
    ~ # openssl version
    OpenSSL 0.9.8j 07 Jan 2009

    奇怪,明明 clientkey.pem 和 client.crt 是刚生成的配套文件,其中前者保存私钥,后者则是用户证书(包含公钥),怎么会出错?

    于是切换到 Windows 平台再验证一番,虽然版本不同,但仍然报错,只不过显示的错误信息不一样

    d:>openssl pkcs12 -export -inkey clientkey.pem -in client.crt -out client.p12
    WARNING: can't open config file: /usr/local/ssl/openssl.cnf
    Loading 'screen' into random state - done
    unable to load certificates
    
    d:>openssl version
    WARNING: can't open config file: /usr/local/ssl/openssl.cnf
    OpenSSL 1.0.1f 6 Jan 2014

    没办法,只得祭出调试器,到源码内部看个究竟。既然在 Windows 平台,就用顺手的 Visual Studio。打开(以前建立的)OpenSSL 解决方案(OpenSSL 版本号 1.0.1f),切换到 Debug 配置,确保该配置实际包含【-Zi】调试选项。

    准备下断点,该在哪里下呢?

    由于错误信息为 unable to load certificates ,其中过程肯定涉及到证书加载函数,所以应该是 load_cert(不要问我为什么知道,因为我熟悉^_^)。如果不熟悉,可以在 Source Insight 中用 F7 调出【Browse Project Symbols】对话框,输入猜测的关键字,比如 load/certificate 等,也能找到 load_cert 函数。

    反正不论如何,找到了怀疑函数 load_cert。在 Visual Studio 中新建此函数的断点,并在 IDE 中配置好命令参数和工作目录。F5 启动,果然命中,说明成功了一半。继续跟踪,最后得到出错的位置如下(位于文件 cryptopempem_lib.c 中)

       695
       696        buf[254]='';
       697        for (;;)
       698            {
       699            i=BIO_gets(bp,buf,254);
       700
       701            if (i <= 0)
       702                {
       703                PEMerr(PEM_F_PEM_READ_BIO,PEM_R_NO_START_LINE);
       704                goto err; // <-- 【在此处出错,并跳出】
       705                }
       706

    出错的调用栈为

    openssl.exe!main
    openssl.exe!do_cmd
    openssl.exe!pkcs12_main
    openssl.exe!load_certs
    openssl.exe!load_certs_crls
    libeay32.dll!PEM_X509_INFO_read_bio
    libeay32.dll!PEM_read_bio

    自底向上逐个切换调用栈,查看是哪里引发了问题,结果在 pkcs12_main 函数(文件 appspkcs12.c)中,发现如下一处调用

       461
       462        /* Load in all certs in input file */
       463        if(!(options & NOCERTS))
       464            {
       465            certs = load_certs(bio_err, infile, FORMAT_PEM, NULL, e,
       466                                "certificates"); // <-- 【以 PEM 格式加载证书】
       467            if (!certs)
       468                goto export_end;
       469

    原来证书要求以 PEM 格式加载,回过头用文本编辑器打开 client.crt。果然,此文件是 DER 格式的。

    名不副实,自然是要出问题的。

    原因知道了,解决办法也立即有了。使用如下命令将证书转为 PEM 格式

    d:>openssl x509 -in client.crt -inform der -out client.pem

    然后再执行一次 pkcs12 命令

    d:>openssl pkcs12 -export -inkey clientkey.pem -in client.pem -out client.p12

    问题得到解决。

    自然想到,难道 pkcs12 命令就不提供 -inform 的格式转换选项?
    运行命令【openssl pkcs12 ?】,可以看到确实没有提供 -inform 选项,看来还是有改进的空间。

  • 相关阅读:
    FZU Monthly-201906 tutorial
    FZU Monthly-201906 获奖名单
    FZU Monthly-201905 tutorial
    BZOJ1009 GT考试
    BZOJ2428 均分数据
    模拟退火
    BZOJ3680 吊打XXX
    BZOJ4818 序列计数
    BZOJ4103 异或运算
    BZOJ3512 DZY Loves Math IV
  • 原文地址:https://www.cnblogs.com/efzju/p/4966519.html
Copyright © 2020-2023  润新知