RSA_PKCS1加解密

RSA_PKCS1加解密

解密失败

背景

分批加解密参数

# 分批加解密,如果加解密字符串大于这个值则分批加解密,尽量不要使用使用,因为加密分批的话,解密目前还不知道如果解,以同样大小分片还是解不了的
block_size = 2048000

加密

    def rsa_pkcs1_encrypt(self, plaintext, private_key):
        """
        RSA私钥加密
        :param plaintext: 明文
        :param private_key: 私钥
        :return:
        """
        # 密钥长度为1024时,最大加密块
        max_encrypt_block = self.block_size
        # 填充方式
        padding = RSA.pkcs1_padding

        # 字节编码
        plainBytes = plaintext.encode(encoding='utf-8')

        # 明文长度
        plaintext_length = len(plainBytes)

        # 不需要分段加密
        if plaintext_length < max_encrypt_block:
            return b64encode(private_key.private_encrypt(plainBytes, padding)).decode(encoding='utf-8')

        # 分段加密
        offset = 0
        ciphers = []
        while plaintext_length - offset > 0:
            if plaintext_length - offset > max_encrypt_block:
                ciphers.append(private_key.private_encrypt(plainBytes[offset:offset + max_encrypt_block], padding))
            else:
                ciphers.append(private_key.private_encrypt(plainBytes[offset:], padding))
            offset += max_encrypt_block
        return b64encode(b"".join(ciphers)).decode(encoding='utf-8')

解密

    def rsa_pkcs1_decrypt(self, ciphertext, public_key):
        """
        RSA公钥解密
        :param ciphertext:
        :param public_key:
        :return:
        """
        encrypt_result = b64decode(ciphertext)
        # 密钥长度为1024时,最大解密块
        max_decrypt_block = self.block_size
        # 加密结果长度
        encrypt_result_length = len(encrypt_result)
        # 填充方式
        padding = RSA.pkcs1_padding

        # 不需要分段解密
        if encrypt_result_length < max_decrypt_block:
            plains = public_key.public_decrypt(encrypt_result, padding)
            return plains.decode(encoding='utf-8')

        # 分段解密
        offset = 0
        plains = []
        while encrypt_result_length - offset > 0:
            if encrypt_result_length - offset > max_decrypt_block:
                plains.append(public_key.public_decrypt(encrypt_result[offset:offset + max_decrypt_block], padding))
            else:
                plains.append(public_key.public_decrypt(encrypt_result[offset:], padding))
            offset += max_decrypt_block
        return b"".join(plains).decode(encoding='utf-8')

使用以上方法加密之后解密异常

Traceback (most recent call last):
  File "x x x", line 594, in rsa_pkcs1_decrypt
    plains.append(public_key.public_decrypt(encrypt_result[offset:offset + max_decrypt_block], padding))
  File "x x x/lib64/python3.6/site-packages/M2Crypto/RSA.py", line 72, in public_decrypt
    return m2.rsa_public_decrypt(self.rsa, data, padding)
M2Crypto.RSA.RSAError: wrong tag

原因

上述加密方法加密后字段超过一定长度block_size就会采取分批解密方式,但是分批解密无法识别密文,所以导致解密失败

Linux生密钥

利用私钥生成公钥

1.openssl genrsa -out rsa_private_key_2048.pem 2048 #生成rsa私钥,X509编码,2048位
2.openssl pkcs8 -in rsa_private_key_2048.pem -out rsa_private_key_2048_pkcs8.pem -nocrypt -topk8 #转换为PKCS#8编码
3.openssl rsa -in rsa_private_key_2048.pem -out rsa_public_key_2048.pem -pubout #导出对应的公钥,X509编码
  1. 生成2048位的rsa私钥,默认是X509编码,这一步生成的私钥文件只供第2、3步使用,并没有实际用处;
  2. 使用第1步生成的私钥文件生成PKCS#8编码的私钥文件,这一步生成的文件为最终使用的私钥文件;
  3. 使用第1步生成的私钥文件生成对应的公钥文件,这一步生成的公钥文件为最终使用的公钥文件;

通过Java代码读取rsa_private_key_2048_pkcs8.pem私钥文件生成数字签名,使用rsa_public_key_2048.pem公钥文件验证数字签名

参考

https://blog.csdn.net/zhang854429783/article/details/80140072

加密失败

现象

Traceback (most recent call last):
  File "x x x x.py", line 166, in <module>
    private_key = read_key(private_key_path, "private")
  File "x x x x.py", line 53, in read_key
    return RSA.load_key_bio(rea_key)
  File "x x x x/venv/lib64/python3.6/site-packages/M2Crypto/RSA.py", line 398, in load_key_bio
    rsa_error()
  File "x x x x/venv/lib64/python3.6/site-packages/M2Crypto/RSA.py", line 333, in rsa_error
    raise RSAError(Err.get_error_message())
M2Crypto.RSA.RSAError: wrong tag

原因

加密所用的key非法

M2Crypto安装

yum install build-essential libssl-dev swig python3-dev -y

pip install m2Crypto

本文作者:朝圣

本文链接:www.zh-noone.cn/2021/1/RSA_PKCS1加解密

版权声明:本博客所有文章除特别声明外,均采用CC BY-NC-SA 3.0许可协议。转载请注明出处!

asyncio多线程RuntimeError
0 条评论