python R-S-A

713 阅读3分钟


import rsa
from rsa import common, transform, core
import os
import base64

'''测试OK
参数中的密钥对privkey.d, privkey.n与pubkey.e, pubkey.n互换可实现:
公钥加密和私钥解密
私钥加密和公钥解密
(d,n 可计算出e)
'''


class MyRSA_SupportPrivEncrypt():
    def __init__(self):
        self.prikey_str = '''-----BEGIN RSA PRIVATE KEY-----
        MIICYQIBAAKBgQC4g/9Twin752ycsqaNZW737Ciz/BPLQV7qPzfjXok9VX0L0qft
        ZwzjE+tffMygicI+h3FSlEzHH9S6uz+9btAZz7pxLXU46H5jsDNPjck8Z6EFLJQz
        FmK4O9hxsx5S/SgqL+IgbShyO0LnCLFeSAxTjOa5obB40bTiZZQ9rS3atwIDAQAB
        AoGAe5Yt1nQemtMPNIWUePCPuw861BLrTyCh6lQdovUXBzXTY6/dOm3je9VDudll
        VcHvkOI3TRB3vIfdfJUeGo/NVFOSXXA6sUb+uwCfekycumgnxwBm5iL55/Xg1whg
        gkhjKavRVUEZWjt70Z9/vLR1euObW+olMMCVGoc3rWo2aAECRQD9aPtHqzRY/e7t
        MoR83dsm3nIimWM/RoT2tP2E4Mzy8IVswhGvRVuKnlKPfxRsv8gwVD/2kbnqjjMs
        H1/du5CKUMWLNwI9ALpmwuZXW+rruosUvQM5mpUxZ8lyV5Z0NXdikCf2ywP9UqVk
        FU4sfYfUxM2gcGJrS0iD207vUTc6axTsgQJFAKyI5tVkFq8kraFoDNargwPS3qj6
        AJ3bWLpUfmwTVtdttZpYBAxuz6Xwp8u1vWVRqm5lXmt1yryNdv/qmK3yf7X8ypM/
        Ajxeb7+gmXPNMj6hRhF4t890dMJjUhXD+P45jOsCBEvYqpgbiPguUeYLUiWfFAC8
        LCXJCFyswhyAgY1M3YECRQCDX9Ctsjyg4k/xsip4vJuVEDfhyb9T7vl9bc78lFns
        gy8vpSmpwTwietMgw9fNj40AMX2rFpMeQIdwi4YhFIJI1gGZlg==
        -----END RSA PRIVATE KEY-----
        '''
        self.pubkey_str = '''-----BEGIN RSA PUBLIC KEY-----
        MIGJAoGBALiD/1PCKfvnbJyypo1lbvfsKLP8E8tBXuo/N+NeiT1VfQvSp+1nDOMT
        6198zKCJwj6HcVKUTMcf1Lq7P71u0BnPunEtdTjofmOwM0+NyTxnoQUslDMWYrg7
        2HGzHlL9KCov4iBtKHI7QucIsV5IDFOM5rmhsHjRtOJllD2tLdq3AgMBAAE=
        -----END RSA PUBLIC KEY-----
        '''
        # self.key_private = rsa.PrivateKey.load_pkcs1(self.prikey_str)
        # self.key_public = rsa.PublicKey.load_pkcs1(self.pubkey_str)
    # #======================加载密钥 start================

    def readFilePrivateKeyStr(self, strPrikeyPathFile):
        with open(strPrikeyPathFile, 'r') as f:
            self.prikey_str = f.read()
            # print(self.prikey_str)
        self.key_private = rsa.PrivateKey.load_pkcs1(self.prikey_str)

    def readFilePublicKeyStr(self, strPublicPathFile):
        with open(strPublicPathFile, 'r') as f:
            self.pubkey_str = f.read()
        self.key_public = rsa.PublicKey.load_pkcs1(self.pubkey_str)

    def getPrivateKeyFromStr(self, strPrikey=None):
        if strPrikey!=None:
            self.prikey_str = strPrikey
        self.key_private = rsa.PrivateKey.load_pkcs1(self.prikey_str)

    def getPublicKeyFromStr(self, strPubkey=None):
        if strPubkey!=None:
            self.pubkey_str = strPubkey
        self.key_public = rsa.PublicKey.load_pkcs1(self.pubkey_str)
    # ======================加载密钥 end================
    def _pad_for_encryption(self, message, target_length):

        max_msglength = target_length - 11
        msglength = len(message)

        if msglength > max_msglength:
            raise OverflowError(
                "%i bytes needed for message, but there is only"
                " space for %i" % (msglength, max_msglength)
            )

        padding = b""
        padding_length = target_length - msglength - 3

        while len(padding) < padding_length:
            needed_bytes = padding_length - len(padding)
            new_padding = os.urandom(needed_bytes + 5)
            new_padding = new_padding.replace(b"\x00", b"")
            padding = padding + new_padding[:needed_bytes]

        assert len(padding) == padding_length

        return b"".join([b"\x00\x02", padding, b"\x00", message])

    def create_KeyPare(self):  # 生成公钥和私钥
        (pubkey, privkey) = rsa.newkeys(1024)
        pub = pubkey.save_pkcs1()
        with open('public.pem', 'wb+')as f:
            f.write(pub)

        pri = privkey.save_pkcs1()
        with open('private.pem', 'wb+')as f:
            f.write(pri)

    def _encrypt(self, data: bytes, pubkey_e, pubkey_n):  # 可换为prikey_d, prikey_n
        keylength = common.byte_size(pubkey_n)
        padded = self._pad_for_encryption(data, keylength)
        num = transform.bytes2int(padded)
        decrypto = core.encrypt_int(num, pubkey_e, pubkey_n)
        out = transform.int2bytes(decrypto)
        # print(out)
        return out

    def _decrypt(self, data: bytes, prikey_d, prikey_n):  # 可换为pubkey_e, pubkey_n
        num = transform.bytes2int(data)
        decrypto = core.decrypt_int(num, prikey_d, prikey_n)
        out = transform.int2bytes(decrypto)
        sep_idx = out.index(b"\x00", 2)
        out = out[sep_idx + 1:]
        return out

    # ===================

    def longEncrypt_Base64_PriKey(self, data: bytes):  # , privkey: rsa.PrivateKey
        '''
        私钥加密
        '''
        length = len(data)
        keylength = common.byte_size(self.key_private.n)
        # print(keylength)
        default_length = keylength-11
        # 长度不用分段
        if length < default_length:
            return base64.b64encode(self._encrypt(data, self.key_private.d, self.key_private.n))
        # 需要分段
        offset = 0
        res = []
        while length - offset > 0:
            if length - offset > default_length:
                res.append(self._encrypt(
                    data[offset:offset + default_length], self.key_private.d, self.key_private.n))
            else:
                res.append(self._encrypt(
                    data[offset:], self.key_private.d, self.key_private.n))
            offset += default_length
            # print(res)
        byte_data = b''.join(res)
        #print(byte_data)
        return base64.b64encode(byte_data)

    def longDecrypt_Base64_PubKey(self, data: bytes):  # , pubkey:rsa.PublicKey
        '''
        公钥解密
        '''
        crypt_data = base64.b64decode(data)
        key_length = rsa.common.byte_size(self.key_public.n)
        if len(crypt_data) % key_length != 0:
            # 如果数据长度不是key_length的整数倍, 则数据是无效的
            return None

        length = len(crypt_data)
        if length < key_length:
            return self._decrypt(crypt_data, self.key_public.e, self.key_public.n).decode('utf8')
        # 需要分段
        offset = 0
        res = []
        while length - offset > 0:
            if length - offset > key_length:
                res.append(self._decrypt(
                    crypt_data[offset:offset + key_length], self.key_public.e, self.key_public.n))
            else:
                res.append(self._decrypt(
                    crypt_data[offset:], self.key_public.e, self.key_public.n))
            offset += key_length

        return b''.join(res).decode('utf8')


if __name__ == '__main__':
    
    data = """
    光头强其实说起来,也是一个吃货,在这部动画片中,总是能听见光头强说,想吃这个想吃那个的。
    只不过很多时候,因为经济的问题,光头强根本就吃不起,所以这也就练就了,光头强一身好厨艺。
    不过更多的时候,光头强吃的,还是别人做的。那么,接下来的话,我们就来看看,光头强吃过的那些食物,
    没想到这最贵的,竟然要上万元,不得不说,光头强真的是太豪气了。
    泡面是光头强,除了馒头之外,吃的第二多的食物,选择泡面的缘故,一方面自然是因为便宜,
    还有一方面就是,泡面只需要泡一泡就好了,十分节约时间。不过,这泡面吃多了之后,光头强对于泡面,
    也是十分的讨厌。说起来,以前很多人小的时候,也总是喜欢吃泡面,可是长大之后,对于这种食物,
    其实都挺抵触的。
    牛肉面应该算光头强,为数不多吃的东西了,因为对于光头强来说,这牛肉面其实挺贵的,经常吃也吃不起。
    而这个牛肉面的味道,自然是挺不错的,不然那个时候,光头强也不会因为这一碗牛肉面,就直接和赵琳吵了起来。
    而且说起来,这牛肉面里的牛肉,看起来也是挺多的,光头强吃的时候,应该很开心吧。
    """
    data2b = data.encode('utf8')
   
    a = MyRSA_SupportPrivEncrypt()
    a.getPrivateKeyFromStr()
    a.getPublicKeyFromStr()
    # a.create_KeyPare()
    # if 1>0:
    #     exit(0)
    '''a.readFilePrivateKeyStr('private.pem')'''
    pwd = a.longEncrypt_Base64_PriKey(data2b)
    print (pwd)
    '''f = open('passwd.data', 'r')
    pwd=f.read()
    f.close()'''
    ddata = a.longDecrypt_Base64_PubKey(pwd)
    print(ddata)