python rsa 加密解密

创建日期: 2024-04-01 19:20 | 作者: 风波 | 浏览次数: 15 | 分类: Python

文档:https://stuvel.eu/python-rsa-doc/usage.html#generating-keys

安装 rsa

pip install rsa -i https://mirrors.aliyun.com/pypi/simple/  --trusted-host mirrors.aliyun.com

加密、解密

python 版 rsa 库不提供密钥直接加密信息的函数,只提供公钥加密+私钥解密。但是它提供一对 sign()verify() 函数来验证文件签名。sign() 函数需要使用密钥加密文件的 hash值,而使用 verify() 函数解密这个 hash 值,所以从这一对函数里面找到了私钥加密+公钥解密的方式。

class RsaPrivate():
    def __init__(self, pem):
        if isinstance(pem, str) or isinstance(pem, io.BytesIO):
            # read from filepath
            with open(pem, 'rb') as f:
                self.privkey = rsa.PrivateKey.load_pkcs1(f.read())
                self.pubkey = rsa.PublicKey(self.privkey.n, self.privkey.e)
        elif isinstance(pem, bytes):
            # read from memory
            self.privkey = rsa.PrivateKey.load_pkcs1(pem)
            self.pubkey = rsa.PublicKey(self.privkey.n, self.privkey.e)
        elif isinstance(pem, rsa.PrivateKey):
            self.privkey = pem
            self.pubkey = rsa.PublicKey(self.privkey.n, self.privkey.e)
        else:
            raise Exception("unsupported pem type")

    def padding(self, msg):
        keylength = self.keylen()
        assert isinstance(msg, bytes)

        if len(msg) >= keylength:
            raise Exception(f"msg length is too long: {len(msg)} > {keylength - 1}")

        mlen = len(msg)
        bmlen = mlen.to_bytes(1, 'big')
        logger.debug("meglen: {} {} , keylength: {}".format(str(bmlen), len(msg), keylength))

        okmsg = bmlen + b'\xff' * (keylength - mlen - 1) + msg
        assert len(okmsg) == keylength

        return okmsg


    def keylen(self):
        keylength = rsa.common.byte_size(self.privkey.n)
        return keylength


    def encrypt(self, message):
        cleartext = message
        if isinstance(message, bytes):
            cleartext = message
        elif isinstance(message, str):
            cleartext = message.encode()
        else:
            raise Exception("unsupported message type, should be bytes or str")
        keylength = self.keylen()

        padded = self.padding(cleartext)
        logger.debug(f"padded type: {type(padded)} , length: {len(padded)}")
        payload = rsa.transform.bytes2int(padded)
        encrypted = self.privkey.blinded_encrypt(payload)
        block = rsa.transform.int2bytes(encrypted, keylength)
        return block


    def decrypt(self, message):
        msg = message
        if isinstance(message, bytes):
            msg = message
        elif isinstance(message, str):
            msg = message.encode()
        else:
            raise Exception("unsupported message type, should be bytes or str")

        keylength = rsa.common.byte_size(self.privkey.n)
        ened = rsa.transform.bytes2int(msg)
        deed = rsa.core.decrypt_int(ened, self.pubkey.e, self.pubkey.n)
        txt = rsa.transform.int2bytes(deed, keylength)
        logger.debug(f"txt[0] type: {type(txt[0])}", txt[0])
        mlen = txt[0]
        originmsg = txt[keylength - mlen:]
        return originmsg


keylen = 512 # 1024
(pubkey, priv_key) = rsa.newkeys(keylen)
#xx = priv_key.save_pkcs1()
#rsaprivkey = RsaPrivate(xx)
rsaprivkey = RsaPrivate(priv_key)
15 浏览
14 爬虫
0 评论