• python RSA加密、解密、签名、验签


    RSA公私钥生成地址

    http://www.metools.info/code/c80.html

    Python RAS 加密、解密、签名、验签

    python中用于RSA加解密的库有好久个,本文主要讲解rsa 库对于RSA加密、解密、签名、验签的知识点。 

    推荐使用rsa库

    知识基础

    加密是为了保证传输内容隐私,签名是为了保证消息真实性。

    服务器存私钥,客户端存公钥。(服务器和客户端关系可以考虑为 1:N)

    客户端往服务器传输内容,更多考虑是隐私性,所以公钥签名、私钥解密。

    服务器往客户端传输内容,更多考虑真实性,所以私钥签名,公钥验签。

    消息的摘要生的算法常用的是MD5或者SHA1,消息内容不一样,生成的摘要信息一定不一样。

    真实性的考虑一方面是内容由私钥拥有者发出,另一方面内容在传输过程中没有改变过,所以签名的对象是传输信息生成的消息摘要(摘要内容短,签名也会快些)。

    每次加密的长度需要小于密钥长度-特殊位(128位公钥,最长可加密128-11=117位明文)。

    每次解密的长度需要小于密钥的长度(128位私钥解密,解密密文长度需要小于等于128位)。

    如果加解密内容过长,就需要分段加密、解密。

    PEM格式的密钥为base64位文本格式。

    # -*- coding: UTF-8 -*-
    # ! /usr/bin/env python
    import base64
    import rsa
    from rsa import common
    
    
    # 使用 rsa库进行RSA签名和加解密
    class RsaUtil(object):
        PUBLIC_KEY_PATH = '/tmp/gbzj/public_key.pem'  # 公钥
        PRIVATE_KEY_PATH = '/tmp/gbzj/private_key.pem'  # 私钥
    
        # 初始化key
        def __init__(self,
                     company_pub_file=PUBLIC_KEY_PATH,
                     company_pri_file=PRIVATE_KEY_PATH):
    
            if company_pub_file:
                self.company_public_key = rsa.PublicKey.load_pkcs1_openssl_pem(open(company_pub_file).read())
            if company_pri_file:
                self.company_private_key = rsa.PrivateKey.load_pkcs1(open(company_pri_file).read())
    
        def get_max_length(self, rsa_key, encrypt=True):
            """加密内容过长时 需要分段加密 换算每一段的长度.
                :param rsa_key: 钥匙.
                :param encrypt: 是否是加密.
            """
            blocksize = common.byte_size(rsa_key.n)
            reserve_size = 11  # 预留位为11
            if not encrypt:  # 解密时不需要考虑预留位
                reserve_size = 0
            maxlength = blocksize - reserve_size
            return maxlength
    
        # 加密 支付方公钥
        def encrypt_by_public_key(self, message):
            """使用公钥加密.
                :param message: 需要加密的内容.
                加密之后需要对接过进行base64转码
            """
            encrypt_result = b''
            max_length = self.get_max_length(self.company_public_key)
            while message:
                input = message[:max_length]
                message = message[max_length:]
                out = rsa.encrypt(input, self.company_public_key)
                encrypt_result += out
            encrypt_result = base64.b64encode(encrypt_result)
            return encrypt_result
    
        def decrypt_by_private_key(self, message):
            """使用私钥解密.
                :param message: 需要加密的内容.
                解密之后的内容直接是字符串,不需要在进行转义
            """
            decrypt_result = b""
    
            max_length = self.get_max_length(self.company_private_key, False)
            decrypt_message = base64.b64decode(message)
            while decrypt_message:
                input = decrypt_message[:max_length]
                decrypt_message = decrypt_message[max_length:]
                out = rsa.decrypt(input, self.company_private_key)
                decrypt_result += out
            return decrypt_result
    
        # 签名 商户私钥 base64转码
        def sign_by_private_key(self, data):
            """私钥签名.
                :param data: 需要签名的内容.
                使用SHA-1 方法进行签名(也可以使用MD5)
                签名之后,需要转义后输出
            """
            signature = rsa.sign(data, priv_key=self.company_private_key,
                                 hash_method='SHA-256')  # 加密方式Use 'MD5', 'SHA-1', 'SHA-224', SHA-256', 'SHA-384' or 'SHA-512'
            return base64.b64encode(signature)
    
        def verify_by_public_key(self, message, signature):
            """公钥验签.
                :param message: 验签的内容.
                :param signature: 对验签内容签名的值(签名之后,会进行b64encode转码,所以验签前也需转码).
            """
            signature = base64.b64decode(signature)
            return rsa.verify(message, signature, self.company_public_key)
    
    
    message = 'appId=f334fdgd&bizContent={"authCode":"4196a49571e747259028fa25df330604b4f6d301"}&timestamp=2022-08-01 10:20:08'
    print("明文内容:>>> ")
    print(message)
    rsaUtil = RsaUtil()
    encrypy_result = rsaUtil.encrypt_by_public_key(message)
    print("加密结果:>>> ")
    print(encrypy_result)
    decrypt_result = rsaUtil.decrypt_by_private_key(encrypy_result)
    print("解密结果:>>> ")
    print(decrypt_result)
    
    sign = rsaUtil.sign_by_private_key(message)
    print("签名结果:>>> ")
    print(sign)
    print("验签结果:>>> ")
    print(rsaUtil.verify_by_public_key(message, sign))


  • 相关阅读:
    python学习笔记(excel中处理日期格式)
    python学习笔记(生成xml)
    python学习笔记(接口自动化框架 V1.0)
    python学习笔记(excel+unittest)
    刷题[RoarCTF 2019]Easy Java
    刷题[GKCTF2020]
    php bypass disable function
    刷题[MRCTF2020]Ezpop
    刷题[安恒DASCTF2020四月春季赛]Ez unserialize
    刷题[HFCTF2020]EasyLogin
  • 原文地址:https://www.cnblogs.com/zhaoyingjie/p/16540261.html
Copyright © 2020-2023  润新知