• 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')
  • 相关阅读:
    Qt编写物联网管理平台35实时曲线
    Qt开发经验小技巧221225
    Qt编写物联网管理平台36通信协议
    Qt编写物联网管理平台34地图按钮
    【Python】抛砖引玉连续有序数组的排序问题
    java经验总结
    0618
    面试_子数组类问题
    【segmentation fault】vsnprintf错误用法
    Sword jemalloc使用小结
  • 原文地址:https://www.cnblogs.com/yunlong-study/p/14538390.html
Copyright © 2020-2023  润新知