X509数字证书结构和实例

https://wenku.baidu.com/view/988c262aed630b1c59eeb56b.html

这篇讲得很细

https://wyxwyx46941930.github.io/2019/01/22/X-509/   这篇也可以

X509标准方式生成的证书

1.生成证书、公钥文件、私钥文件

import time

from M2Crypto import X509, EVP, RSA, ASN1

def issuer_name():

    """

    证书发行人名称(专有名称)。

    Parameters:

        none

    Return:

        X509标准的发行人obj.

    """

    issuer = X509.X509_Name()

    issuer.C = "CN"                # 国家名称

    issuer.CN = "*.jb51.net"       # 普通名字

    issuer.ST = "Hunan Changsha"

    issuer.L = "Hunan Changsha"

    issuer.O = "Geekso Company Ltd"

    issuer.OU = "Geekso Company Ltd"

    issuer.Email = "123456@qq.com"

    return issuer

def make_request(bits, cn):

    """

    创建一个X509标准的请求。

    Parameters:

        bits = 证书位数

        cn = 证书名称

    Return:

        返回 X509 request 与 private key (EVP).

    """

    rsa = RSA.gen_key(bits, 65537, None) 

    pk = EVP.PKey()

    pk.assign_rsa(rsa)

    req = X509.Request()

    req.set_pubkey(pk)

    name = req.get_subject()

    name.C = "US"

    name.CN = cn

    req.sign(pk,'sha256')

    return req, pk

def make_certificate_valid_time(cert, days):

    """

    从当前时间算起证书有效期几天。

    Parameters:

        cert = 证书obj

        days = 证书过期的天数

    Return:

        none

    """

    t = long(time.time()) # 获取当前时间

    time_now = ASN1.ASN1_UTCTIME()

    time_now.set_time(t)

    time_exp = ASN1.ASN1_UTCTIME()

    time_exp.set_time(t + days * 24 * 60 * 60)

    cert.set_not_before(time_now)

    cert.set_not_after(time_exp)

def make_certificate(bits):

    """

    创建证书

    Parameters:

        bits = 证快的位数

    Return:

        证书, 私钥 key (EVP) 与 公钥 key (EVP).

    """

    req, pk = make_request(bits, "localhost")

    puk = req.get_pubkey()

    cert = X509.X509()

    cert.set_serial_number(1) # 证书的序例号

    cert.set_version(1) # 证书的版本

    cert.set_issuer(issuer_name()) # 发行人信息

    cert.set_subject(issuer_name()) # 主题信息

    cert.set_pubkey(puk)

    make_certificate_valid_time(cert, 365) # 证书的过期时间

    cert.sign(pk, 'sha256')

    return cert, pk, puk

# 开始创建

cert, pk, puk= make_certificate(1024)

cert.save_pem('jb51.net-cret.pem')

pk.save_key('jb51.net-private.pem',cipher = None, callback = lambda: None)

puk.get_rsa().save_pub_key('jb51.net-public.pem')

2.用证书加密、私钥文件解密

def geekso_encrypt_with_certificate(message, cert_loc):

    """

    cert证书加密,可以用私钥文件解密.

    Parameters:

        message = 要加密的串

        cert_loc = cert证书路径

    Return:

        加密串 or 异常串

    """

    cert = X509.load_cert(cert_loc)

    puk = cert.get_pubkey().get_rsa() # get RSA for encryption

    message = base64.b64encode(message)

    try:

        encrypted = puk.public_encrypt(message, RSA.pkcs1_padding)

    except RSA.RSAError as e:

        return "ERROR encrypting " + e.message

    return encrypted

encrypted = geekso_encrypt_with_certificate('www.jb51.net','jb51.net-cret.pem')

print '加密串',encrypted

def geekso_decrypt_with_private_key(message, pk_loc):

    """

    私钥解密证书生成的加密串

    Parameters:

        message = 加密的串

        pk_loc = 私钥路径

    Return:

        解密串 or 异常串

    """

    pk = RSA.load_key(pk_loc) # load RSA for decryption

    try:

        decrypted = pk.private_decrypt(message, RSA.pkcs1_padding)

        decrypted = base64.b64decode(decrypted)

    except RSA.RSAError as e:

        return "ERROR decrypting " + e.message

    return decrypted

print '解密串',geekso_decrypt_with_private_key(encrypted, 'jb51.net-private.pem')

3.用私钥加密、证书解密

def geekso_encrypt_with_private_key(message,pk_loc):

    """

    私钥加密

    Parameters:

        message = 加密的串

        pk_loc = 私钥路径

    Return:

        加密串 or 异常串

    """

    ReadRSA = RSA.load_key(pk_loc);

    message = base64.b64encode(message)

    try:

        encrypted = ReadRSA.private_encrypt(message,RSA.pkcs1_padding)

    except RSA.RSAError as e:

        return "ERROR encrypting " + e.message

    return encrypted

encrypted = geekso_encrypt_with_private_key('www.jb51.net', 'jb51.net-private.pem')

print encrypted

def geekso_decrypt_with_certificate(message, cert_loc):

    """

    cert证书解密.

    Parameters:

        message = 要解密的串

        cert_loc = cert证书路径

    Return:

        解密后的串 or 异常串

    """

    cert = X509.load_cert(cert_loc)

    puk = cert.get_pubkey().get_rsa()

    try:

        decrypting = puk.public_decrypt(message, RSA.pkcs1_padding)

        decrypting = base64.b64decode(decrypting)

    except RSA.RSAError as e:

        return "ERROR decrypting " + e.message

    return decrypting

decrypting = geekso_decrypt_with_certificate(encrypted, 'jb51.net-cret.pem')

print decrypting

4.用私钥签名、证书验证签名

def geekso_sign_with_private_key(message, pk_loc, base64 = True):

    """

    私钥签名

    Parameters:

        message = 待签名的串

        pk_loc = 私钥路径

        base64 = True(bease64处理) False(16进制处理)

    Return:

        签名后的串 or 异常串

    """

    pk = EVP.load_key(pk_loc)

    pk.sign_init()

    try:

        pk.sign_update(message)

        signature = pk.sign_final()

    except EVP.EVPError as e:

        return "ERROR signature " + e.message

    return signature.encode('base64') if base64 is True else signature.encode('hex')

signature = geekso_sign_with_private_key('www.jb51.net','jb51.net-private.pem')

print signature

def geekso_verifysign_with_certificate(message, signature, cert_loc, base64 = True):

    """

    证书验证签名

    Parameters:

        message = 原来签名的串

        signature = 签名后的串

        cert_loc = 证书路径文件

        base64 = True(bease64处理) False(16进制处理)

    Return:

        成功or失败串 or 异常串

    """

    signature = signature.decode('base64') if base64 is True else signature.decode('hex')

    cert = X509.load_cert(cert_loc)

    puk = cert.get_pubkey().get_rsa()

    try:

        verifyEVP = EVP.PKey()

        verifyEVP.assign_rsa(puk)

        verifyEVP.verify_init()

        verifyEVP.verify_update(message)

        verifysign = verifyEVP.verify_final(signature)

        if verifysign == 1 :

            return '成功'

        else :

            return '失败'

    except EVP.EVPError as e:

        return "ERROR Verify Sign " + e.message

    

print geekso_verifysign_with_certificate('www.jb51.net', signature, 'jb51.net-cret.pem')
原文地址:https://www.cnblogs.com/yunlong-study/p/14538390.html