Python利用获得的密钥进行RSA解密

问题遇到的现象和发生背景

最近在做一个案例,全部都到位了,就在快要成功之时遇到了一个加密的问题解密不了。这是一种rsa加密,要解开的话我要获得他的私钥又或者叫密钥。密钥获得后,我利用在线的rsa解密网站,通过密钥将密文解了出来,经验证解出来的内容是正确的。但是问题来了,我会到网站上在线解密但是我不会在python里进行rsa解密,网上找了很多办法都不得而终,很多都是讲怎么创建公钥私钥然后利用这个进行加解密,但是都没有讲如何利用已获得的私钥(密钥)对密文进行解密。


# 这是已经获得的密钥
-----BEGIN PRIVATE KEY-----
MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAIXbcicDUMXbwTQa
O2z7mJ6kt+S71AO91jq0j3sN7rmtasfMo2ZRiGrZejkaNxAPSjVJ9U/8FJG7JZHE
HzOv2mtOqkSYt2Si8kofnU424jbZcxzm4zS8IeLO/FOXNYTNJ2SoJmMs1kqUZ91b
zZlZ+Mh6ZReK4OcM/lJtg21MfU31AgMBAAECgYABp4avqMDU0TSAGlrlq+5k95A2
SYQDT9NYAmdLlA6BSP1q3sKePx+6glmaXxKTJj06j2FyzaDLdE6wkIX6M5A1grxe
Jdgn4nNFVuphoW3NZNQlKeAXzHt8d6wCvlk2HuROPCDtAIPgE9k8JOZmOM8+BJ3L
mDBmgRQ1SxgowFtheQJBAMMG42KQQ3FjoJ3QKQzMixJQ6/6Fgat7KnRb+ru/E/ue
KTO0nO/JY3PZyy56t0ClPV/KVgcGFJ9j7qhJN1v+OiMCQQCvtMyZ7bHArbOPy7VX
xmYMLZI+kQChoLsmAtK9Itr6fN3EWqlWsG3Z+imFpVVkFVYNY7JZgXoZTw1ksHZA
GV0HAkB+Mu7g0MlTjkxY0mI9zf4QFB0hzfJirIiEUyCkbLjZkTbIJo+G+qJITR6V
LQN36XUVjzCrytt9aIT+kKIp/RBRAkB99mijhXLkBeLvmIN13Ka13km0jvFb7cWd
F3MK4p0H7FJz/ObfXfYyyZPQ2tlfuagKS0nFvvvQfwrD/3mWtFgrAkBN3xf+3JbG
2hauKJGx0yNbfCmweA3iqD7n3oml6fq7uL+pC4UXnvKtubUzVR1kJbRJAmR9YO4u
cv36qKveFFoS
-----END PRIVATE KEY-----

# 这是对应的密文
7bb70f65ec6a8e4e4f932df55f308f33a78636248dbacb76ebf88ea1cfd385e001fd36ede8ef61a1b4be44a69ad2c4d97adef8dd28c8ebfce8d0cd7a66fba772959dab9573592182c92e2bbc89991e6a5bbca75e92ac2bbb62f1a7c13d0fedf1b9d4bb679834f6d564152cebe592a893d71c9901116a41f9f654ecb5876e1e3f5bc696181543b86c8a2cafdb900a1c9d33841e803a0a008315aea8236cf8c9998658bb2f2699460bfbd3ee33ae94387817836213bb27f3aada76a2cb4e8fb30cb4c778206217ac3e6ae0082b7f05d2d092c6c01c20d0f46e897f67c6f0c37abf8669efb48590ef3689ace8df063d289b27432bc2b6216113f7a5f9c901e78a7f

# 这是解密后的正确结果
'''
足熔控线改荷一部磨,温尽即烧壁开锁配循控线模车。
'''
自行查找的相关资料链接

http://t.csdn.cn/9SI7N
http://t.csdn.cn/sPxLa

问题相关代码,及运行结果
# 这是看了第一个链接所写的代码

import base64
from Crypto.Cipher import PKCS1_v1_5 as Cipher_pksc1_v1_5
from Crypto.PublicKey import RSA


def decrpt(password, private_key):
    encrypt_text = password.encode('utf-8')
    private_key = '-----BEGIN PRIVATE KEY-----\n' + private_key + '\n-----END PRIVATE KEY-----'
    print(private_key)
    rsakey = RSA.importKey(private_key)
    cipher = Cipher_pksc1_v1_5.new(rsakey)  # 创建用于执行pkcs1_v1_5加密或解密的密码
    text = cipher.decrypt(base64.b64decode(encrypt_text), 1024)
    print(text.decode('utf-8'))
    return text.decode('utf-8')


if __name__ == '__main__':
    wo = "7bb70f65ec6a8e4e4f932df55f308f33a78636248dbacb76ebf88ea1cfd385e001fd36ede8ef61a1b4be44a69ad2c4d97adef8dd28c8ebfce8d0cd7a66fba772959dab9573592182c92e2bbc89991e6a5bbca75e92ac2bbb62f1a7c13d0fedf1b9d4bb679834f6d564152cebe592a893d71c9901116a41f9f654ecb5876e1e3f5bc696181543b86c8a2cafdb900a1c9d33841e803a0a008315aea8236cf8c9998658bb2f2699460bfbd3ee33ae94387817836213bb27f3aada76a2cb4e8fb30cb4c778206217ac3e6ae0082b7f05d2d092c6c01c20d0f46e897f67c6f0c37abf8669efb48590ef3689ace8df063d289b27432bc2b6216113f7a5f9c901e78a7f"
    private_key = '''MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAIXbcicDUMXbwTQa
    O2z7mJ6kt+S71AO91jq0j3sN7rmtasfMo2ZRiGrZejkaNxAPSjVJ9U/8FJG7JZHE
    HzOv2mtOqkSYt2Si8kofnU424jbZcxzm4zS8IeLO/FOXNYTNJ2SoJmMs1kqUZ91b
    zZlZ+Mh6ZReK4OcM/lJtg21MfU31AgMBAAECgYABp4avqMDU0TSAGlrlq+5k95A2
    SYQDT9NYAmdLlA6BSP1q3sKePx+6glmaXxKTJj06j2FyzaDLdE6wkIX6M5A1grxe
    Jdgn4nNFVuphoW3NZNQlKeAXzHt8d6wCvlk2HuROPCDtAIPgE9k8JOZmOM8+BJ3L
    mDBmgRQ1SxgowFtheQJBAMMG42KQQ3FjoJ3QKQzMixJQ6/6Fgat7KnRb+ru/E/ue
    KTO0nO/JY3PZyy56t0ClPV/KVgcGFJ9j7qhJN1v+OiMCQQCvtMyZ7bHArbOPy7VX
    xmYMLZI+kQChoLsmAtK9Itr6fN3EWqlWsG3Z+imFpVVkFVYNY7JZgXoZTw1ksHZA
    GV0HAkB+Mu7g0MlTjkxY0mI9zf4QFB0hzfJirIiEUyCkbLjZkTbIJo+G+qJITR6V
    LQN36XUVjzCrytt9aIT+kKIp/RBRAkB99mijhXLkBeLvmIN13Ka13km0jvFb7cWd
    F3MK4p0H7FJz/ObfXfYyyZPQ2tlfuagKS0nFvvvQfwrD/3mWtFgrAkBN3xf+3JbG
    2hauKJGx0yNbfCmweA3iqD7n3oml6fq7uL+pC4UXnvKtubUzVR1kJbRJAmR9YO4u
    cv36qKveFFoS'''
    print(wo)
    print('当前密文长度:', len(wo))
    decrpt(wo, private_key)
# 运行结果

D:\项目\venv\Scripts\python.exe D:/项目/test.py
7bb70f65ec6a8e4e4f932df55f308f33a78636248dbacb76ebf88ea1cfd385e001fd36ede8ef61a1b4be44a69ad2c4d97adef8dd28c8ebfce8d0cd7a66fba772959dab9573592182c92e2bbc89991e6a5bbca75e92ac2bbb62f1a7c13d0fedf1b9d4bb679834f6d564152cebe592a893d71c9901116a41f9f654ecb5876e1e3f5bc696181543b86c8a2cafdb900a1c9d33841e803a0a008315aea8236cf8c9998658bb2f2699460bfbd3ee33ae94387817836213bb27f3aada76a2cb4e8fb30cb4c778206217ac3e6ae0082b7f05d2d092c6c01c20d0f46e897f67c6f0c37abf8669efb48590ef3689ace8df063d289b27432bc2b6216113f7a5f9c901e78a7f
当前密文长度: 512
-----BEGIN PRIVATE KEY-----
MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAIXbcicDUMXbwTQa
    O2z7mJ6kt+S71AO91jq0j3sN7rmtasfMo2ZRiGrZejkaNxAPSjVJ9U/8FJG7JZHE
    HzOv2mtOqkSYt2Si8kofnU424jbZcxzm4zS8IeLO/FOXNYTNJ2SoJmMs1kqUZ91b
    zZlZ+Mh6ZReK4OcM/lJtg21MfU31AgMBAAECgYABp4avqMDU0TSAGlrlq+5k95A2
    SYQDT9NYAmdLlA6BSP1q3sKePx+6glmaXxKTJj06j2FyzaDLdE6wkIX6M5A1grxe
    Jdgn4nNFVuphoW3NZNQlKeAXzHt8d6wCvlk2HuROPCDtAIPgE9k8JOZmOM8+BJ3L
    mDBmgRQ1SxgowFtheQJBAMMG42KQQ3FjoJ3QKQzMixJQ6/6Fgat7KnRb+ru/E/ue
    KTO0nO/JY3PZyy56t0ClPV/KVgcGFJ9j7qhJN1v+OiMCQQCvtMyZ7bHArbOPy7VX
    xmYMLZI+kQChoLsmAtK9Itr6fN3EWqlWsG3Z+imFpVVkFVYNY7JZgXoZTw1ksHZA
    GV0HAkB+Mu7g0MlTjkxY0mI9zf4QFB0hzfJirIiEUyCkbLjZkTbIJo+G+qJITR6V
    LQN36XUVjzCrytt9aIT+kKIp/RBRAkB99mijhXLkBeLvmIN13Ka13km0jvFb7cWd
    F3MK4p0H7FJz/ObfXfYyyZPQ2tlfuagKS0nFvvvQfwrD/3mWtFgrAkBN3xf+3JbG
    2hauKJGx0yNbfCmweA3iqD7n3oml6fq7uL+pC4UXnvKtubUzVR1kJbRJAmR9YO4u
    cv36qKveFFoS
-----END PRIVATE KEY-----
Traceback (most recent call last):
  File "D:/项目/test.py", line 35, in <module>
    decrpt(wo, private_key)
  File "D:/项目/test.py", line 12, in decrpt
    text = cipher.decrypt(base64.b64decode(encrypt_text), 1024)
  File "D:\Python\lib\site-packages\Crypto\Cipher\PKCS1_v1_5.py", line 174, in decrypt
    raise ValueError("Ciphertext with incorrect length (not %d bytes)" % k)
ValueError: Ciphertext with incorrect length (not 128 bytes)

Process finished with exit code 1
# 这是看了第二个链接所写的代码

import rsa


# rsa解密
def rsaDecrypt(str, pk):
    # 私钥解密
    content = rsa.decrypt(str, pk)
    con = content.decode("utf-8")
    return con


if __name__ == "__main__":
    # 密文
    str = '7bb70f65ec6a8e4e4f932df55f308f33a78636248dbacb76ebf88ea1cfd385e001fd36ede8ef61a1b4be44a69ad2c4d97adef8dd28c8ebfce8d0cd7a66fba772959dab9573592182c92e2bbc89991e6a5bbca75e92ac2bbb62f1a7c13d0fedf1b9d4bb679834f6d564152cebe592a893d71c9901116a41f9f654ecb5876e1e3f5bc696181543b86c8a2cafdb900a1c9d33841e803a0a008315aea8236cf8c9998658bb2f2699460bfbd3ee33ae94387817836213bb27f3aada76a2cb4e8fb30cb4c778206217ac3e6ae0082b7f05d2d092c6c01c20d0f46e897f67c6f0c37abf8669efb48590ef3689ace8df063d289b27432bc2b6216113f7a5f9c901e78a7f'
    # 密钥
    pk = '''-----BEGIN PRIVATE KEY-----
MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAIXbcicDUMXbwTQa
O2z7mJ6kt+S71AO91jq0j3sN7rmtasfMo2ZRiGrZejkaNxAPSjVJ9U/8FJG7JZHE
HzOv2mtOqkSYt2Si8kofnU424jbZcxzm4zS8IeLO/FOXNYTNJ2SoJmMs1kqUZ91b
zZlZ+Mh6ZReK4OcM/lJtg21MfU31AgMBAAECgYABp4avqMDU0TSAGlrlq+5k95A2
SYQDT9NYAmdLlA6BSP1q3sKePx+6glmaXxKTJj06j2FyzaDLdE6wkIX6M5A1grxe
Jdgn4nNFVuphoW3NZNQlKeAXzHt8d6wCvlk2HuROPCDtAIPgE9k8JOZmOM8+BJ3L
mDBmgRQ1SxgowFtheQJBAMMG42KQQ3FjoJ3QKQzMixJQ6/6Fgat7KnRb+ru/E/ue
KTO0nO/JY3PZyy56t0ClPV/KVgcGFJ9j7qhJN1v+OiMCQQCvtMyZ7bHArbOPy7VX
xmYMLZI+kQChoLsmAtK9Itr6fN3EWqlWsG3Z+imFpVVkFVYNY7JZgXoZTw1ksHZA
GV0HAkB+Mu7g0MlTjkxY0mI9zf4QFB0hzfJirIiEUyCkbLjZkTbIJo+G+qJITR6V
LQN36XUVjzCrytt9aIT+kKIp/RBRAkB99mijhXLkBeLvmIN13Ka13km0jvFb7cWd
F3MK4p0H7FJz/ObfXfYyyZPQ2tlfuagKS0nFvvvQfwrD/3mWtFgrAkBN3xf+3JbG
2hauKJGx0yNbfCmweA3iqD7n3oml6fq7uL+pC4UXnvKtubUzVR1kJbRJAmR9YO4u
cv36qKveFFoS
-----END PRIVATE KEY-----'''
    content = rsaDecrypt(str, pk)
    print("解密后明文:\n%s" % content)
# 运行结果

D:\项目\venv\Scripts\python.exe D:/项目/test2.py
Traceback (most recent call last):
  File "D:/项目/test2.py", line 44, in <module>
    content = rsaDecrypt(str, pk)
  File "D:/项目/test2.py", line 19, in rsaDecrypt
    content = rsa.decrypt(str, pk)
  File "D:\Python\lib\site-packages\rsa\pkcs1.py", line 255, in decrypt
    blocksize = common.byte_size(priv_key.n)
AttributeError: 'str' object has no attribute 'n'

Process finished with exit code 1

我的解答思路和尝试过的方法

根据第一个链接的报错信息我估计是长度问题,我将这个案例分享个前端的一些朋友,他们也说是这个问题,用他们的语言将密文进行分段解密后再拼接得到了最终的正确结果,但是无奈的是我还是不知道在python里面要怎么写。

我想要达到的结果

另外说一声,我在在线网站里我直接把密文和密钥输进去是能直接得到结果的('https://the-x.cn/cryptography/Rsa.aspx

  1. 解密,一次只能处理128个字节,所以要分段批处理。

  2. 要先把16进制字符转换成字节格式,一个字节=两个16进制字符。

代码已经验证通过,代码仅供学习交流!
# coding=utf-8
from Crypto.Cipher import PKCS1_v1_5
from Crypto.PublicKey import RSA

def private_key(key_file=None):
    key = key_file and open(key_file).read()
    if not key:
        key = '''-----BEGIN PRIVATE KEY-----
        MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAIXbcicDUMXbwTQaO2z7mJ6kt+S71AO91jq0j3sN7rmtasfMo2ZRiGrZejkaNxAPSjVJ9U/8FJG7JZHE
        HzOv2mtOqkSYt2Si8kofnU424jbZcxzm4zS8IeLO/FOXNYTNJ2SoJmMs1kqUZ91bzZlZ+Mh6ZReK4OcM/lJtg21MfU31AgMBAAECgYABp4avqMDU0TSAGlrlq+5k95A2
        SYQDT9NYAmdLlA6BSP1q3sKePx+6glmaXxKTJj06j2FyzaDLdE6wkIX6M5A1grxeJdgn4nNFVuphoW3NZNQlKeAXzHt8d6wCvlk2HuROPCDtAIPgE9k8JOZmOM8+BJ3L
        mDBmgRQ1SxgowFtheQJBAMMG42KQQ3FjoJ3QKQzMixJQ6/6Fgat7KnRb+ru/E/ueKTO0nO/JY3PZyy56t0ClPV/KVgcGFJ9j7qhJN1v+OiMCQQCvtMyZ7bHArbOPy7VX
        xmYMLZI+kQChoLsmAtK9Itr6fN3EWqlWsG3Z+imFpVVkFVYNY7JZgXoZTw1ksHZAGV0HAkB+Mu7g0MlTjkxY0mI9zf4QFB0hzfJirIiEUyCkbLjZkTbIJo+G+qJITR6V
        LQN36XUVjzCrytt9aIT+kKIp/RBRAkB99mijhXLkBeLvmIN13Ka13km0jvFb7cWdF3MK4p0H7FJz/ObfXfYyyZPQ2tlfuagKS0nFvvvQfwrD/3mWtFgrAkBN3xf+3JbG
        2hauKJGx0yNbfCmweA3iqD7n3oml6fq7uL+pC4UXnvKtubUzVR1kJbRJAmR9YO4ucv36qKveFFoS
        -----END PRIVATE KEY-----
        '''
    return RSA.importKey(key)

def cipher_pksc1(rsakey=private_key()):
    return PKCS1_v1_5.new(rsakey)

def decrypt(encrypt_text, cipher=cipher_pksc1(), sentinel=None):
    s, t = 0, 128
    result = []
    for i in range(t, t + len(encrypt_text), t):
        decrypt_text = cipher.decrypt(encrypt_text[s:i], sentinel)
        result.append(decrypt_text.decode('utf-8'))
        s = i
    return ''.join(result)

def func():
    wo = """
    7bb70f65ec6a8e4e4f932df55f308f33a78636248dbacb76ebf88ea1cfd385e001fd36ede8ef61a1b4be44a69ad2c4d97adef8dd28c8ebfce8d0cd7a66fba772
    959dab9573592182c92e2bbc89991e6a5bbca75e92ac2bbb62f1a7c13d0fedf1b9d4bb679834f6d564152cebe592a893d71c9901116a41f9f654ecb5876e1e3f
    5bc696181543b86c8a2cafdb900a1c9d33841e803a0a008315aea8236cf8c9998658bb2f2699460bfbd3ee33ae94387817836213bb27f3aada76a2cb4e8fb30c
    b4c778206217ac3e6ae0082b7f05d2d092c6c01c20d0f46e897f67c6f0c37abf8669efb48590ef3689ace8df063d289b27432bc2b6216113f7a5f9c901e78a7f
    """
    wo = bytes.fromhex(wo)
    print('当前密文长度:', len(wo))
    print(decrypt(wo))

if __name__ == '__main__':
    func()

img

刚好做了一个rsa解密的demo,参考以下代码:

import base64
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_v1_5 as PKCS1_cipher  
from urllib.parse import unquote


def get_key(key_file):
    with open(key_file) as f:
        data = f.read()  # 获取,密钥信息
        key = RSA.importKey(data)
    return key


def decrypt_data(encrypt_msg):
    private_key = get_key('rsa.pem')  # 读取私钥信息 已知的私钥保存为了一个rsa.pem文件,也可直接写在这里
    cipher = PKCS1_cipher.new(private_key)  # 生成一个解密的类
    back_text = cipher.decrypt(base64.b64decode(encrypt_msg), 0)  # 进行解密
    return back_text.decode()  # 对文本内容进行解码

# 需要解密的文本
encrypt_text = "IFNlLRQW4eZGTU3btauN26QHC9/YBg02XQL4NCRbsDjYhe27+1mBwL66Aitn7kHv2t4B/DyiSuXVVnUEw/5cP+c3n5iqTrQnUYxTGodmOQnL5U/Fpl+sjJQoY9SlDODyy7FFYjfsAiXs5IDosGqwsPvXNZrT4bJMyY7/pSm6oQ+xLhvuDl4sywvQoed3ou67QmenOGKsQ9w4E0/0W8xF8FXFfcdLUELPD45ESxxsowZA/q4zGp6XbpuNvx6EkGv1JBqyK7KjDiOYsxYpa8Hh62U9jCgUiKr2+TkYOzEH5E0sy8ZBtSl+cW1x+0Os7F7GYf7MFwGiegy/UukdWNUf/Q=="
decrypt_text = unquote(decrypt_data(encrypt_text))  # 解密
print(decrypt_text)

错误原因:
一般加解密算法中用的私钥,需要byte数组类型
BEGIN PRIVATE KEY 这种是openssl私钥格式文件,相当于把byte数组编码过了

解决方法:
网上搜一下 python openssl 私钥解密,可以找到不少参考代码
比如 https://blog.csdn.net/xc_zhou/article/details/121584039

生成私钥和公钥的方法
def savekey():
"""
新建公钥和私钥并保存到本地
:return:
"""
# 生成公钥和私钥
pubkey, privkey = rsa.newkeys(1024)
pub = pubkey.save_pkcs1()
# 公钥
with open('./keys/public.pem', 'wb') as w_pub:
w_pub.write(pub)
# 私钥
pri = privkey.save_pkcs1()
with open('../keys/private.pem', 'wb') as w_pri:
w_pri.write(pri)
return "保存成功"