zoukankan      html  css  js  c++  java
  • 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')
  • 相关阅读:
    【转+补充】在OpenCV for Android 2.4.5中使用SURF(nonfree module)
    Delphi StarOffice Framework Beta 1.0 发布
    Angular ngIf相关问题
    angularjs文档下载
    公众号微信支付开发
    公众号第三方平台开发 教程六 代公众号使用JS SDK说明
    公众号第三方平台开发 教程五 代公众号处理消息和事件
    公众号第三方平台开发 教程四 代公众号发起网页授权说明
    公众号第三方平台开发 教程三 微信公众号授权第三方平台
    公众号第三方平台开发 教程二 component_verify_ticket和accessToken的获取
  • 原文地址:https://www.cnblogs.com/yunlong-study/p/14538390.html
Copyright © 2011-2022 走看看