shivam_patel
shivam_patel

Reputation: 1

RSA Encryption and Decryption using 2 files

So I have created 2 files one for encryption and other for decryption. I am able to encrypt the text but when it comes to decrypting I get an error (See bottom of question). I am able to export the Private_key.pem, public_key.pem and even the secret.txt file. I am able to read the private_key.pem in my decrypt.py script but it errors out. I believe the script thinks that the private_key it is using is not correct. I know this is wrong as I generate the public and private key, use the public key to encrypt and private to decrypt. If anyone can shed some light on this it would be greatly appreciated.

Encrypt.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()

decrypt.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()

ERROR:

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.

New Error:

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>

Upvotes: 0

Views: 1684

Answers (1)

dave_thompson_085
dave_thompson_085

Reputation: 38771

Topaco is right: you're actually generating four keypairs, throwing away the first two, writing the private key from the third and the public key from the fourth. These keys don't match and thus don't work. You should generate one keypair and use the private and public halves of that pair. The following slightly simplified code works for me:

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'

The caveat that this only works for limited amount of data remains.

Upvotes: 1

Related Questions