0

I'm trying to encrypt and decrypt a file with PyCryptodome but without success. I can encrypt strings and data just fine but when trying to encrypt files it fails. I have 2 problems, first is that I can't encrypt larger strings. Witch i tried to solve by reading the file with a buffer. Second is that when I try to encrypt it as smaller buffers it just gives me an error "raise ValueError("Ciphertext with incorrect length.")"

My code looks like this:

from Crypto.Cipher import PKCS1_OAEP
import binascii
import ast

file_to_encrypt = "file_example_MP3_700KB.mp3"
buffer_size = 65536  # 64kb

input_file = open(file_to_encrypt, "rb")
output_file = open(file_to_encrypt + ".encrypted", "wb")


# Import keys
pub = open("publickey.txt", "rb")
pubKey = RSA.importKey(pub.read())
pub.close()

priv = open("privatekey.txt", "rb")
keyPair = RSA.importKey(priv.read())
priv.close()
# --------------------------------------------------------------


# Encrypt
encryptor = PKCS1_OAEP.new(pubKey)
buffer = input_file.read(buffer_size)

while len(buffer) > 0:
    encrypted = encryptor.encrypt(buffer)
    output_file.write(encrypted)
    buffer = input_file.read(buffer_size)

input_file.close()
output_file.close()
# --------------------------------------------------------------


input_file = open(file_to_encrypt + ".encrypted", "rb")
output_file = open(file_to_encrypt + ".decrypted", "wb")


# Decrypt
decryptor = PKCS1_OAEP.new(keyPair)
buffer = input_file.read(buffer_size)

while len(buffer) > 0:
    decrypted = decryptor.decrypt(ast.literal_eval(str(buffer)))
    output_file.write(decrypted)
    buffer = input_file.read(buffer_size)

input_file.close()
output_file.close()
# --------------------------------------------------------------

And generating the keys looks like this:

from Crypto.Cipher import PKCS1_OAEP
import binascii
import ast

# key generation
keyPair = RSA.generate(3072*2)
pubKey = keyPair.publickey()
# --------------------------------------------------------------

# Export keys
pub = open("publickey.txt", "wb")
pub.write(pubKey.exportKey('PEM'))
pub.close()

priv = open("privatekey.txt", "wb")
priv.write(keyPair.exportKey('PEM'))
priv.close()
# --------------------------------------------------------------

# Import keys
pub = open("publickey.txt", "rb")
pubKey = RSA.importKey(pub.read())
pub.close()

priv = open("privatekey.txt", "rb")
keyPair = RSA.importKey(priv.read())
priv.close()
# --------------------------------------------------------------

# encryption
msg = '550011'
encryptor = PKCS1_OAEP.new(pubKey)
encrypted = encryptor.encrypt(msg.encode())
# --------------------------------------------------------------

# decryption
decryptor = PKCS1_OAEP.new(keyPair)
decrypted = str(decryptor.decrypt(ast.literal_eval(str(encrypted))))[2:-1]
# --------------------------------------------------------------

print("Encrypted:", binascii.hexlify(encrypted))
print("Decrypted:", decrypted)

if msg == decrypted:
    print("PASSED!")
else:
    print("FAILED!")

Changing buffer_size fixes the first problem (that the data I'm trying to encrypt is too large.) But I still can't decrypt my file after encrypting it.

Generating and importing keys works just fine. And encrypting and decrypting with them works just fine as well. As long as I'm only encrypting small strings and not files.

  • 2
    RSA can only encrypt a small amount of data, namely as large as the key size minus a value that depends on the padding variant, s. [here, sec. *message*](https://pycryptodome.readthedocs.io/en/latest/src/cipher/oaep.html#Crypto.Cipher.PKCS1_OAEP.PKCS1OAEP_Cipher.encrypt). Increasing the key size is not an option because the performance of RSA breaks down. Thus, for larger amounts of data, [hybrid encryption](https://en.wikipedia.org/wiki/Hybrid_cryptosystem) should be used (e.g. AES and RSA). – Topaco Mar 15 '22 at 08:52

0 Answers0