【问题标题】:RSA Encryption and Decryption using 2 filesRSA加密和解密使用2个文件
【发布时间】:2021-08-13 03:32:07
【问题描述】:

所以我创建了 2 个文件,一个用于加密,另一个用于解密。我能够加密文本,但在解密时出现错误(见问题底部)。我能够导出 Private_key.pem、public_key.pem 甚至是 secret.txt 文件。我可以在我的 decrypt.py 脚本中读取 private_key.pem,但它会出错。我相信脚本认为它使用的 private_key 不正确。我知道这是错误的,因为我生成了公钥和私钥,使用公钥加密并使用私钥解密。如果有人能对此有所了解,将不胜感激。

加密.py

from Crypto import Cipher
from Crypto.Cipher import PKCS1_OAEP
from Crypto.PublicKey import RSA

from Crypto.PublicKey.pubkey import pubkey

def privKEY():
    private_key = RSA.generate(4096)
    return private_key

def pubKey():
    public_Key = privKEY().publickey()
    return public_Key

def convertPrivKey():
    private_pem = privKEY().exportKey().decode()
    with open('private_pem.pem','w') as pr:
        pr.write(private_pem)
    return private_pem

def convertPubKey():
    public_pem = pubKey().exportKey().decode()
    with open('public_pem.pem','w') as pu:
        pu.write(public_pem)
    return public_pem

def encrypt():
    privKEY()
    pubKey()
    convertPrivKey()
    convertPubKey()
    message = 'Testing RSA Encryption'
    message = message.encode()
    pu_key = RSA.importKey(open('public_pem.pem','r').read())
    print(pu_key)
    cipher = PKCS1_OAEP.new(pu_key)
    cipher_text = cipher.encrypt(message)
    with open('secret.txt','w') as f:
        f.write(str(cipher_text))
encrypt()

解密.py

from Crypto.Cipher import PKCS1_OAEP
from Crypto.PublicKey import RSA

def load_secure_file():
    return open('secret.txt','r').read()

def pr_key_read():
    pr_key = RSA.importKey(open('private_pem.pem','r').read())
    return pr_key

def decrypt():
    encrypted_text = load_secure_file()
    pr_key = pr_key_read()
    decrypt = PKCS1_OAEP.new(pr_key)
    decrypted_message = decrypt.decrypt(encrypted_text)
    return decrypted_message
decrypt()

错误:

PS Y:\Python\RSA> & C:/Anaconda/python.exe y:/Python/RSA/decrypt.py
Traceback (most recent call last):
  File "y:/Python/RSA/decrypt.py", line 19, in <module>
    decrypt()
  File "y:/Python/RSA/decrypt.py", line 17, in decrypt
    decrypted_message = decrypt.decrypt(encrypted_text)
  File "C:\Anaconda\lib\site-packages\Crypto\Cipher\PKCS1_OAEP.py", line 195, in decrypt
    raise ValueError("Ciphertext with incorrect length.")
ValueError: Ciphertext with incorrect length.

新错误:

Traceback (most recent call last):
  File "y:/Python/RSA/decrypt.py", line 19, in <module>
    decrypt()
  File "y:/Python/RSA/decrypt.py", line 14, in decrypt
    encrypted_text = load_secure_file()
  File "y:/Python/RSA/decrypt.py", line 7, in load_secure_file
    return open('secret.txt','r').read()
  File "C:\Anaconda\lib\encodings\cp1252.py", line 23, in decode
    return codecs.charmap_decode(input,self.errors,decoding_table)[0]
UnicodeDecodeError: 'charmap' codec can't decode byte 0x8d in position 30: character maps to <undefined>

【问题讨论】:

  • 不,它不会“认为私人钥匙不正确”。它在那里说:“长度不正确的密文”。这是因为您将加密值转换为字符串,但加密值是任意位 (Python bytes) 并且不是有效字符,因此转换为字符串会破坏和破坏您的数据,因此可能会读取为文本(这是默认值)。 使用 Python 的二进制 I/O。 您还应该知道,直接使用 RSA 加密数据非常有限,因此很少使用;在您的情况下,限制约为 200 个字节,可能只有 50 个字符甚至更少。
  • 正如@dave_thompson_085 所说,您应该以二进制模式而不是 utf-8 字符串模式打开 secrets.txt 文件。
  • @dave_thompson_085 我将 secret.txt 的输出更新为“wb”,现在我收到了这个新错误。
  • 看来你必须在解密方面做与str()相反的事情。
  • 在切换到二进制模式(wb,rb)以写入和读取有关secret.txt的str()调用必须也被删除(实际上str() 应该会发生运行时错误)。

标签: python-3.x cryptography rsa private-key public-key


【解决方案1】:

Topaco 是对的:您实际上是在生成 四个 密钥对,丢弃前两个,从第三个写入私钥,从第四个写入公钥。这些键不匹配,因此不起作用。您应该生成 一个 密钥对并使用 那个 对的私有和公共部分。以下稍微简化的代码对我有用:

from Crypto import Cipher
from Crypto.Cipher import PKCS1_OAEP
from Crypto.PublicKey import RSA

# privKEY,pubKey
private_key = RSA.generate(2048) # shortened for testing
public_key = private_key.publickey()
# 'convert' really store
with open('private.pem','w') as pr:
  pr.write(private_key.exportKey().decode())
with open('public.pem','w') as pu:
  pu.write(public_key.exportKey().decode())

# encrypt
message = 'Testing RSA'.encode()
pu_key = RSA.importKey(open('public.pem','r').read())
ciphertext = PKCS1_OAEP.new(pu_key).encrypt(message)
with open('secret.txt','wb') as f:
  f.write(ciphertext)

# decrypt
ciphertext = open('secret.txt','rb').read()
pr_key = RSA.importKey(open('private.pem','r').read())
decrypted = PKCS1_OAEP.new(pr_key).decrypt(ciphertext)
print(decrypted)

-->
b'Testing RSA'

这仅适用于有限数据量的警告仍然存在。

【讨论】:

  • 天哪……现在可以了。非常感谢您的帮助。
猜你喜欢
  • 2017-05-24
  • 2015-06-13
  • 1970-01-01
  • 2015-02-27
  • 1970-01-01
  • 2023-04-05
  • 1970-01-01
  • 1970-01-01
  • 2011-05-27
相关资源
最近更新 更多