python证书生成篇

def generate_adhoc_ssl_pair(cn=None):
    from datetime import datetime as dt
    from datetime import timedelta
    try:
        from cryptography import x509
        from cryptography.x509.oid import NameOID
        from cryptography.hazmat.backends import default_backend
        from cryptography.hazmat.primitives import hashes
        from cryptography.hazmat.primitives.asymmetric import rsa
    except ImportError:
        raise TypeError("Using ad-hoc certificates requires the cryptography library.")
    pkey = rsa.generate_private_key(
        public_exponent=65537, key_size=2048, backend=default_backend()
    )

    # pretty damn sure that this is not actually accepted by anyone
    if cn is None:
        cn = u"*"

    # subject:使用者
    subject = x509.Name(
        [
            x509.NameAttribute(NameOID.ORGANIZATION_NAME, "我自己"),
            x509.NameAttribute(NameOID.COMMON_NAME, '127.0.0.1'),
            x509.NameAttribute(NameOID.COUNTRY_NAME, 'cn'),
        ]
    )

    # issuer:颁发者
    issuer = x509.Name(
        [
            x509.NameAttribute(NameOID.ORGANIZATION_NAME, "我自己"),
            x509.NameAttribute(NameOID.COMMON_NAME, '127.0.0.1'),
            x509.NameAttribute(NameOID.COUNTRY_NAME, 'cn'),
        ]
    )

    # cert使用私钥签名(.sign(私钥,摘要生成算法,填充方式)),使用x509.CertificateBuilder()方法生成证书,证书属性使用下列函数叠加补充
    cert = (
        x509.CertificateBuilder()
        .subject_name(subject)
        .issuer_name(issuer)
        .public_key(pkey.public_key())
        .serial_number(x509.random_serial_number())
        .not_valid_before(dt.utcnow() + timedelta())
        .not_valid_after(dt.utcnow() + timedelta(days=365)).sign(pkey, hashes.SHA256(), default_backend())
    )
    # 最终生成的证书与密钥对为类对象,要保存在文件中还需要进一步转换成字节格式
    return cert, pkey


if __name__ == '__main__':
    import OpenSSL
    from cryptography.hazmat.primitives import serialization
    cert, pkey = generate_adhoc_ssl_pair()
    print(cert)
    # 将证书类对象转换成PEM格式的字节串
    cert_text = cert.public_bytes(serialization.Encoding.PEM)
    print(cert_text)
    # 将证书字节串保存到文件中
    with open('self_signed.cer', mode='wb') as cert_file:
        cert_file.write(cert_text)

    # 将私钥类对象转换成PEM格式的字节串,encryption_algorithm=serialization.NoEncryption()这里是私钥不加密的意思
    private_text = pkey.private_bytes(
            encoding=serialization.Encoding.PEM,
            format=serialization.PrivateFormat.TraditionalOpenSSL,
            encryption_algorithm=serialization.NoEncryption()
        )
    print(private_text)
    # 将私钥字节串保存到文件中
    with open('self_signed_pkey.key', mode='wb') as pkey_file:
        pkey_file.write(private_text)

    # 在程序中查看证书文件内容,当然也可以在文件夹中去双击self_signed.cer查看
    cert = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM,
                                           cert_text)

    certIssue = cert.get_issuer()
    print("通用名称:           ", cert.get_subject().CN)
    print("机构名:             ", cert.get_subject().O)
    print("机构单元名称:        ", cert.get_subject().OU)
    print("地理位置:            ", cert.get_subject().L)
    print("州/省名:             ", cert.get_subject().ST)
    print("国名:               ", cert.get_subject().C)
    print("证书版本:            ", cert.get_version() + 1)
    print("证书序列号:          ", hex(cert.get_serial_number()))
    print("证书中使用的签名算法: ", cert.get_signature_algorithm().decode("UTF-8"))
    print("颁发者:              ", certIssue.commonName)
    print("有效期从:             ", cert.get_notBefore())
    print("到:                   ", cert.get_notAfter())
    print("证书是否已经过期:      ", cert.has_expired())
    print("公钥长度", cert.get_pubkey().bits())
    print("公钥:\n", OpenSSL.crypto.dump_publickey(OpenSSL.crypto.FILETYPE_PEM,
                                                 cert.get_pubkey()).decode(
        "utf-8"))
    print("主体信息:")

    print("CN : 通用名称  OU : 机构单元名称")
    print("O  : 机构名    L  : 地理位置")
    print("S  : 州/省名   C  : 国名")

    for item in certIssue.get_components():
        print(item[0].decode("utf-8"), "  ——  ", item[1].decode("utf-8"))

    print(cert.get_extension_count())

  • 7
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值