首页 > 解决方案 > 将 PEM 证书解析为 JSON

问题描述

我有一个 PEM 证书,我正在使用openssl它来查看它的内容。是否可以将输出解析为 JSON 格式?也许有一个 Java 库或 Bash 脚本可以做到这一点?

命令:$ openssl x509 -in sample.cer -noout -text

输出:

Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            af:69:46:11:10:bd:82:88
        Signature Algorithm: sha1WithRSAEncryption
        Issuer: C=US, ST=Texas, L=Plano, O=2xoffice, OU=Architecture, CN=Joshua Davies/emailAddress=joshua.davies.tx@gmail.com
        Validity
            Not Before: May 21 21:49:10 2014 GMT
            Not After : Jun 20 21:49:10 2014 GMT
        Subject: C=US, ST=Texas, L=Plano, O=2xoffice, OU=Architecture, CN=Joshua Davies/emailAddress=joshua.davies.tx@gmail.com
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
            RSA Public Key: (512 bit)
                Modulus (512 bit):
                    00:b7:38:0d:e0:ab:37:18:a7:26:95:9d:9e:6f:a2:
                    69:b1:b9:ee:b3:7f:29:04:fb:f0:94:b3:d0:d5:55:
                    c0:d8:6b:14:7f:94:13:3c:d9:a2:61:bf:ba:3f:0a:
                    44:37:dc:18:b5:23:c7:ee:96:2d:7c:d8:92:04:48:
                    74:f8:c6:46:a5
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Subject Key Identifier: 
                1A:A5:C9:C8:36:EA:7D:FA:B4:DF:A4:9C:11:F9:C1:BE:78:C4:42:DD
            X509v3 Authority Key Identifier: 
                keyid:1A:A5:C9:C8:36:EA:7D:FA:B4:DF:A4:9C:11:F9:C1:BE:78:C4:42:DD
                DirName:/C=US/ST=Texas/L=Plano/O=2xoffice/OU=Architecture/CN=Joshua Davies/emailAddress=joshua.davies.tx@gmail.com
                serial:AF:69:46:11:10:BD:82:88

            X509v3 Basic Constraints: 
                CA:TRUE
    Signature Algorithm: sha1WithRSAEncryption
        56:32:44:76:86:8c:08:92:74:71:0e:ac:a6:7d:ba:1d:7c:d3:
        b6:74:ef:27:7a:5e:53:21:fc:8e:eb:26:58:e0:6e:4f:5c:01:
        f1:40:ca:0a:e9:d2:0e:00:60:ae:1f:f6:a5:a4:4c:47:fb:e0:
        68:7f:25:63:ab:60:38:0f:74:94

标签: javabashopensslssl-certificatepem

解决方案


我能够构建一个 Python 脚本来满足您的需求。此脚本采用单个参数,<PEM FILE>并返回带有此证书内容的 JSON 对象。

$ ./pem2json.py <PEM FILE>

注意:脚本可以选择接受第二个参数,-d如果您想查看更多转换,它将打印调试信息。

例子

您可以从本网站下载示例 TLS 证书 - X509 证书示例用于测试和验证。具体来说,我将使用这个 PEM 文件:

下载后,我将它作为参数传递给 Python 脚本:

$ ./pem2json.py 2048b-dsa-example-cert.pem
{"notBefore": "Aug 22 07:27:22 2012 GMT", "serialNumber": "0E02", "notAfter": "Aug 21 07:27:22 2017 GMT", "version": 1, "subject": [[["countryName", "JP"]], [["stateOrProvinceName", "Tokyo"]], [["organizationName", "Frank4DD"]], [["commonName", "www.example.com"]]], "issuer": [[["countryName", "JP"]], [["stateOrProvinceName", "Tokyo"]], [["localityName", "Chuo-ku"]], [["organizationName", "Frank4DD"]], [["organizationalUnitName", "WebCert Support"]], [["commonName", "Frank4DD Web CA"]], [["emailAddress", "support@frank4dd.com"]]]}

代码

$ cat pem2json.py
#!/usr/bin/python

import json
import os
import ssl
import sys
from collections import OrderedDict
from pprint import pprint as pp

def main():
    debug = False
    if len(sys.argv) == 3:
      if sys.argv[2] == "-d":
        debug = True

    if debug:
      print("Python {:s} on {:s}\n".format(sys.version, sys.platform))
      print("cli arg1: {:s}\n".format(sys.argv[1]))

    cert_file_name = os.path.join(os.path.dirname(__file__), sys.argv[1])
    try:
        ordered_dict = OrderedDict()
        ordered_dict = ssl._ssl._test_decode_cert(cert_file_name)
        if debug: pp(ordered_dict)

    except Exception as e:
        print("Error decoding certificate: {:s}\n".format(e))

    print(json.dumps(ordered_dict))

if __name__ == "__main__":
    main()

调试输出

$ ./pem2json.py 2048b-dsa-example-cert.pem -d
Python 2.7.5 (default, Jul 13 2018, 13:06:57)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-28)] on linux2

cli arg1: 2048b-dsa-example-cert.pem

{'issuer': ((('countryName', u'JP'),),
            (('stateOrProvinceName', u'Tokyo'),),
            (('localityName', u'Chuo-ku'),),
            (('organizationName', u'Frank4DD'),),
            (('organizationalUnitName', u'WebCert Support'),),
            (('commonName', u'Frank4DD Web CA'),),
            (('emailAddress', u'support@frank4dd.com'),)),
 'notAfter': 'Aug 21 07:27:22 2017 GMT',
 'notBefore': u'Aug 22 07:27:22 2012 GMT',
 'serialNumber': u'0E02',
 'subject': ((('countryName', u'JP'),),
             (('stateOrProvinceName', u'Tokyo'),),
             (('organizationName', u'Frank4DD'),),
             (('commonName', u'www.example.com'),)),
 'version': 1L}
{"notBefore": "Aug 22 07:27:22 2012 GMT", "serialNumber": "0E02", "notAfter": "Aug 21 07:27:22 2017 GMT", "version": 1, "subject": [[["countryName", "JP"]], [["stateOrProvinceName", "Tokyo"]], [["organizationName", "Frank4DD"]], [["commonName", "www.example.com"]]], "issuer": [[["countryName", "JP"]], [["stateOrProvinceName", "Tokyo"]], [["localityName", "Chuo-ku"]], [["organizationName", "Frank4DD"]], [["organizationalUnitName", "WebCert Support"]], [["commonName", "Frank4DD Web CA"]], [["emailAddress", "support@frank4dd.com"]]]}

参考


推荐阅读