• Python的加密方式:RSA加密


    Python的加密方式:RSA加密

    RSA加密是一种非对称加密,通常使用公钥加密,私钥解密,私钥签名,公钥验签。

    在公开密钥密码体制中,加密密钥(即公开密钥)PK是公开信息,而解密密钥(即秘密密钥)SK是需要保密的.RSA算法通常是先生成一对RSA密钥,其中之一是保密密钥,由用户保存;另一个为公开密钥,可对外公开,甚至可在网络服务器中注册。

    RSA是一种公钥密码算法,加密算法是将明文m(m<n是一个整数)加密成密文c,即明文数字m的 E 次方求mod N,也就是将明文与自己相乘E次,然后结果除以N求余数,余数就是密文c,E和N组合就是公钥;解密算法为将密文c解密为明文m,即密文数字c的D次方求mod N,也就是将密文与自己相乘D次,然后结果除以N求余数,余数就是明文m,D和N组合就是私钥。

    以下是关于RSA生成公钥私钥、加密、解密、加签、验签的示例。

    1、生成公钥私钥:

    from Crypto import Random
    from Crypto.PublicKey import RSA
    
    # 伪随机数生成器
    random_generator = Random.new().read
    # rsa算法生成实例
    rsa = RSA.generate(1024, random_generator)
    # 私钥的生成
    private_pem = rsa.exportKey()
    with open("private.pem", "wb") as f:
        f.write(private_pem)
    # 公钥的生成
    public_pem = rsa.publickey().exportKey()
    with open("public.pem", "wb") as f:
        f.write(public_pem)
    

     生成的公钥私钥文件在项目路径下,也可以直接指定生成文件路径。

    文件样例:

    生成的公钥私钥格式是固定的,秘钥中间无空格无换行,秘钥末尾也空格无换行,如下:

    -----BEGIN PUBLIC KEY-----
    MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDEedv+5NsbqAh6pjOMKF8I7FGa
    et3QMUi0g5xDfQAM219qqXnoPi2hmCMjR8MWJV/zyMZ6IiRG/pvrZ2ZhfDNFdW3Z
    SfHczRUvabABzWAr/57/eDBjswv4RQA+gUS6t8wFY/iV+O3i9+d79iN3VhUogfI3
    3Ru3+RPFeFW88tYUhwIDAQAB
    -----END PUBLIC KEY-----
    
    -----BEGIN RSA PRIVATE KEY-----
    MIICXAIBAAKBgQDEedv+5NsbqAh6pjOMKF8I7FGaet3QMUi0g5xDfQAM219qqXno
    Pi2hmCMjR8MWJV/zyMZ6IiRG/pvrZ2ZhfDNFdW3ZSfHczRUvabABzWAr/57/eDBj
    swv4RQA+gUS6t8wFY/iV+O3i9+d79iN3VhUogfI33Ru3+RPFeFW88tYUhwIDAQAB
    AoGAApzaO5QAg+gioLroEZOR2/UEisjafUPCg0ACynT1lLYwGSOCzv9QrQbwZK42
    HmvF0GCZnxMoJ1eIbEN2PZKgveQ/o4o8OdhuSk8pcDY72QwQHgSh1yfdvqkulo7D
    vdmjz63DVSrknYRQFYSHIwUPVVTWyT80OTCYSn3JGqNKa9kCQQDZUbtlBvcPzP4T
    5hRaH9XvCh3PPusQKGPzVRVLn+qZ30N2PNgttYKRMshlz1WMts2ZAKr3b3BLT6GT
    shE5KatfAkEA53JkuV1vUEMg5j1ClgrwTs65yLWb+NbLH84xekrkkSxCkVjE7J/N
    QV7Uk87na49LuztBaECBmaZyTQnFKk7P2QJAMzcc18lVbmbcNipR/49jJquWrOHi
    GfO64nzZwPHWIx9H0dSzCcquE7QJIF1Fhx0JxRYwNJIRv93rcVhU0MjuNwJAIgI/
    JrXCC4sxpGNQC3gkA5CA4Cs/dfsp8cx8nLmwiFx2k6D1nseEg5yJpAZ9HuL5f9Of
    MtB3uroohYVwAV1/UQJBAIZQkryoOJxPbfWvIIGBOAlS/QqfE5kLV+3L2RUtBlac
    nJykMucrdDx1gVKgoREUElxpYtlWI17h9MeNXRICgIM=
    -----END RSA PRIVATE KEY-----
    

     2、加密(使用公钥加密)

    from Crypto.PublicKey import RSA
    from Crypto.Cipher import PKCS1_v1_5 as Cipher_pkcs1_v1_5
    import base64
    
    # 加密
    message = "Hello,This is RSA加密"
    rsakey = RSA.importKey(open("public.pem").read())
    cipher = Cipher_pkcs1_v1_5.new(rsakey)     #创建用于执行pkcs1_v1_5加密或解密的密码
    cipher_text = base64.b64encode(cipher.encrypt(message.encode('utf-8')))
    print(cipher_text.decode('utf-8'))
    

     加密结果:

    Y1oivzbBDIEWX+NaXYLCJo5A226TmuemketZMUM3U80Rw3gSETjG5rHQ+S++Yao+iGQ5jSJA2yjkDtDAjdvi2VUz15LRSkdeKoliWnWy93KKl+aNEsBl3SUicATUgfNWU5ILo+DiltpF79AfIEhPptAz7+gN11KAf5LjfcQZ2+0=
    

     这里每次使用公钥加密后的结果都不一致,跟对数据的padding即填充有关。

     加密时支持的最大字节数与证书有一定关系。加密时支持的最大字节数:证书位数/8 -11(比如:2048位的证书,支持的最大加密字节数:2048/8 - 11 = 245)

      1024位的证书,加密时最大支持117个字节,解密时为128;
      2048位的证书,加密时最大支持245个字节,解密时为256。

     如果需要加密的字节数超出证书能加密的最大字节数,此时就需要进行分段加密。

     3、解密(使用私钥解密)

    from Crypto.PublicKey import RSA
    from Crypto.Cipher import PKCS1_v1_5 as Cipher_pkcs1_v1_5
    import base64
    
    # 解密
    cipher_text = "Y1oivzbBDIEWX+NaXYLCJo5A226TmuemketZMUM3U80Rw3gSETjG5rHQ+S++Yao+iGQ5jSJA2yjkDtDAjdvi2VUz15LRSkdeKoliWnWy93KKl+aNEsBl3SUicATUgfNWU5ILo+DiltpF79AfIEhPptAz7+gN11KAf5LjfcQZ2+0="
    encrypt_text = cipher_text.encode('utf-8')
    rsakey = RSA.importKey(open("private.pem").read())
    cipher = Cipher_pkcs1_v1_5.new(rsakey)      #创建用于执行pkcs1_v1_5加密或解密的密码
    text = cipher.decrypt(base64.b64decode(encrypt_text), "解密失败")
    print(text.decode('utf-8'))
    

     解密结果,与加密前信息一致:

    Hello,This is RSA加密
    

     4、加签(使用私钥加签)

    使用私钥加签,每次签名是一致的。

    from Crypto.PublicKey import RSA
    from Crypto.Signature import PKCS1_v1_5 as Signature_pkcs1_v1_5
    from Crypto.Hash import SHA
    import base64
    
    #加签
    message = "This is a request message..."
    rsakey = RSA.importKey(open("private.pem").read())
    signer = Signature_pkcs1_v1_5.new(rsakey)
    digest = SHA.new()
    digest.update(message.encode("utf-8"))
    sign = signer.sign(digest)
    signature = base64.b64encode(sign)
    print(signature.decode('utf-8'))
    

     签名结果:

    fd99fQpbH48VT9YQKepyHSip9pwrJkm1PN3ZykHNrfTVk555fv392E7MtbIfcligOCWUx8nd3g+7J0Fo3x+9G1Y6MJs0CuMCbA4qulUMNGjzUpsN1URorMZfPKjPvhf22ARH9qZEnebQ7UUGO3ioy4nylZONb3Ldhga+PKyxYTM=
    

     5、验签(使用公钥验签)

    from Crypto.PublicKey import RSA
    from Crypto.Signature import PKCS1_v1_5 as Signature_pkcs1_v1_5
    from Crypto.Hash import SHA
    import base64
    
    #验签
    message_verify = "This is a request message..."
    signature = "fd99fQpbH48VT9YQKepyHSip9pwrJkm1PN3ZykHNrfTVk555fv392E7MtbIfcligOCWUx8nd3g+7J0Fo3x+9G1Y6MJs0CuMCbA4qulUMNGjzUpsN1URorMZfPKjPvhf22ARH9qZEnebQ7UUGO3ioy4nylZONb3Ldhga+PKyxYTM="
    rsakey = RSA.importKey(open("public.pem").read())
    verifier = Signature_pkcs1_v1_5.new(rsakey)
    hsmsg = SHA.new()
    hsmsg.update(message_verify.encode("utf-8"))
    is_verify = verifier.verify(hsmsg, base64.b64decode(signature))
    print(is_verify)
    

     验签结果:

    True
    
  • 相关阅读:
    U盘禁用工具1.3
    《中文专业论文写作概论》笔记
    基于WAP1.0的手机论坛网站系统
    销售统计SQL
    移动如何保护个人开发者的合法权益?
    c#使用winnet检测网络连接状况
    HBASE客户端的一些参数设置
    代理模式
    使用Eclipse+Axis2生成webservice
    java多线程的理解
  • 原文地址:https://www.cnblogs.com/deliaries/p/13445277.html
Copyright © 2020-2023  润新知