How to encrypt and decrypt AES key using RSA and save to text file
Python, Pycrypto, RSA, AES
I am trying to implement a script that will encrypt a file using a randomly generated AES key and then encrypt the said AES key with the RSA public key. The encrypted AES key will be passed on to authorized persons in possession of the private key to decrypt it. The code looks like this:
from Crypto.PublicKey import RSA from Crypto.Cipher import AES from Crypto import Random RSAkey = '-----BEGIN PUBLIC KEY-----\nSome RSA Key here\n-----END PUBLIC KEY-----' RSAkey = RSA.importKey(RSAkey) key = Random.new().read(32) enc_key = RSAkey.encrypt(key, '') enc_key = str(enc_key) custom_writefile_function('enc_key.txt', enc_key)
I am converting enc_key to a string so that I can write it to a text file, otherwise enc_key.txt will contain garbage. However, the problem is that in another script designed to decrypt enc_key to get the original AES key used to encrypt files, trying to decrypt enc_key that was converted to a string throws an error:
RSAkey.decrypt (str (RSAkey.encrypt (key, ''))) Traceback (last call last): File ", line 1, to File" / usr / lib / python 2.7 / dist-packages / Crypto / PublicKey / RSA .py ", line 174, decrypted return pubkey.pubkey.decrypt (self, ciphertext) File" / usr / lib / python 2.7 / dist-packages / Crypto / PublicKey / pubkey.py ", line 93 decrypted plain text = self._decrypt (ciphertext) File "/ usr / lib / python 2.7 / dist-packages / Crypto / PublicKey / RSA.py", line 237, in _decrypt cp = self.key._blind (ciphertext, r) ValueError: the message is too large
The code looks like this:
RSAkey = custom_readfile_function('private_key.txt', 'r') RSAkey = RSA.importKey(RSAkey) enc_key = custom_readfile_function('enc_key.txt', 'r') aes_key = RSAkey.decrypt(enc_key) custom_writefile_function('key.txt', str(aes_key), 'w')
I believe the problem is type mismatch. RSAkey.encrypt (key, '') returns the type 'tuple', so I believe RSA.decrypt () expects this type as well, but I cannot write this type to a text file. So when I convert it to a string to write to a file, I will need to convert it back to print "tuple" when I decrypt. How can i do this? Or maybe there is a better way to achieve my desired result that I have not considered?
source to share
Use base 64 instead of converting directly to string.
Beware of the documentation of the method
you are using:
Returns: A tuple with two items. The first element is ciphertext of the same type as plaintext (string or long). The second element is always missing. Overrides: pubkey.pubkey.encrypt
In addition, you should heed the following advice:
Note: This function performs a simple, primitive RSA cipher (tutorial). In real applications, you always need to use the correct cryptographic padding, and you should not directly encrypt data using this method. Failure to do so can lead to security vulnerabilities. It is recommended to use the Crypto.Cipher.PKCS1_OAEP or Crypto.Cipher.PKCS1_v1_5 modules instead.
source to share
Even though it has been over one year since you asked this question, I still want to give a real answer to your problem, because I have struggled with this minute myself, but an awkward error, so anyone who comes across this situation, will be able to quickly solve the problem.
First of all, as the other answer suggests, for human readability, I would use base64 encoding:
enc_key = RSAkey.encrypt(key, '') enc_key = base64.b64encode(enc_key)
represents the first tuple value that is generated by the method
(the cipher text itself).
Then when you want to decode the whole thing, you call:
aes_key = RSAkey.decrypt(base64.b64decode(enc_key))
which should give you back the original without
ValueError: Message too large
source to share