Python RSA 文件加解密结果因大文件而异
Python RSA file encrypt-decrypt result varies with large files
我知道 RSA 一次不能加密超过 128 个字节(模数),所以我对文件进行分块加密和解密。但是,如果我的文件大于几 kb,每次我 运行 程序时结果都会改变。有时整个文件被正确加密和解密。有时只有前 100 行,等等。此时我想知道这是否是 Crypto.PublicKey.RSA 模块的可靠性问题。这是我的代码:
def encrypt(file, public_key):
read_size = 128
with open(file, 'rb') as original_file:
e_file = file + '.e'
with open(e_file, 'wb') as encrypted_file:
while True:
file_part = original_file.read(read_size)
if len(filePart) == 0:
break
encrypted_file.write(public_key.encrypt(file_part, None)[0])
os.remove(file)
def decrypt(file, private_key):
read_size = 128
with open(file, 'rb') as encrypted_file:
d_file = file[:-2]
with open(d_file, 'wb') as decrypted_file:
while True:
file_part = encrypted_file.read(read_size)
if len(filePart) == 0:
break
decrypted_file.write(private_key.decrypt(file_part))
os.remove(file)
private_key = RSA.generate(1024)
public_key = RSA.importKey(private_key.publickey().exportKey())
my_file = 'myfile.txt'
encrypt(my_file, public_key)
decrypt(my_file + '.e', private_key)
编辑:: Maarten 的回答是有效的。这是一个具体的例子,说明我如何用他的回答解决我的问题。
我使用了这个导入:
from Crypto.Cipher import PKCS1_OAEP
然后我没有直接使用 public 密钥来加密,而是使用了这个:
cipher = PKCS1_OAEP.new(publicKey)
encryptedFile.write(cipher.encrypt(filePart))
然后我做了类似的解密。
RSA 要求填充是安全的,例如 OAEP 或较旧的、不太安全的 PKCS#1 v1.5 填充。这些带来了一些开销。一般来说,这不是一个大问题,因为经常使用混合密码系统,其中 RSA 与对称密码配对。不错的选择是 RSA-OAEP 和 AES-GCM - 您可能还想先签署明文。
如果您使用原始 RSA,那么如果设置了最高有效位(在左侧,RSA 使用大端/网络顺序),您可能 运行 会遇到麻烦。在那种情况下,明文将被视为与明文相同 模数 N,RSA 计算中使用的模数。
例如 4 % 5 = 4 但 9 % 5 也是 4)。当您执行解密时,即使输入是 9,答案也将是 4。因此,根据明文块的前(少数)位,所有位都将在解密后翻转。
我知道 RSA 一次不能加密超过 128 个字节(模数),所以我对文件进行分块加密和解密。但是,如果我的文件大于几 kb,每次我 运行 程序时结果都会改变。有时整个文件被正确加密和解密。有时只有前 100 行,等等。此时我想知道这是否是 Crypto.PublicKey.RSA 模块的可靠性问题。这是我的代码:
def encrypt(file, public_key):
read_size = 128
with open(file, 'rb') as original_file:
e_file = file + '.e'
with open(e_file, 'wb') as encrypted_file:
while True:
file_part = original_file.read(read_size)
if len(filePart) == 0:
break
encrypted_file.write(public_key.encrypt(file_part, None)[0])
os.remove(file)
def decrypt(file, private_key):
read_size = 128
with open(file, 'rb') as encrypted_file:
d_file = file[:-2]
with open(d_file, 'wb') as decrypted_file:
while True:
file_part = encrypted_file.read(read_size)
if len(filePart) == 0:
break
decrypted_file.write(private_key.decrypt(file_part))
os.remove(file)
private_key = RSA.generate(1024)
public_key = RSA.importKey(private_key.publickey().exportKey())
my_file = 'myfile.txt'
encrypt(my_file, public_key)
decrypt(my_file + '.e', private_key)
编辑:: Maarten 的回答是有效的。这是一个具体的例子,说明我如何用他的回答解决我的问题。 我使用了这个导入:
from Crypto.Cipher import PKCS1_OAEP
然后我没有直接使用 public 密钥来加密,而是使用了这个:
cipher = PKCS1_OAEP.new(publicKey)
encryptedFile.write(cipher.encrypt(filePart))
然后我做了类似的解密。
RSA 要求填充是安全的,例如 OAEP 或较旧的、不太安全的 PKCS#1 v1.5 填充。这些带来了一些开销。一般来说,这不是一个大问题,因为经常使用混合密码系统,其中 RSA 与对称密码配对。不错的选择是 RSA-OAEP 和 AES-GCM - 您可能还想先签署明文。
如果您使用原始 RSA,那么如果设置了最高有效位(在左侧,RSA 使用大端/网络顺序),您可能 运行 会遇到麻烦。在那种情况下,明文将被视为与明文相同 模数 N,RSA 计算中使用的模数。
例如 4 % 5 = 4 但 9 % 5 也是 4)。当您执行解密时,即使输入是 9,答案也将是 4。因此,根据明文块的前(少数)位,所有位都将在解密后翻转。