I am trying to build a module for a CTF I am planning. The idea is that you are given an encrypted file and an RSA public key and have to decrypt the file.
I am intentionally using a weak RSA key (128bit) so that it can be factored and the private exponent deduced. I am encrypting a file using openssl rsautl
with the -raw
padding option like so:
openssl rsautl -encrypt -raw -inkey public_key.pem -pubin -in test.txt -out test.enc
I am then attempting to walk through the exercise, taking the public key and deducing the private exponent from there. Since I have the actual private key, I am able to confirm that I have done this part correctly and have the right primes / private exponent.
In my code I read in the encrypted file, convert it to hex and then perform the decrypt operation on each hex value. This leaves me with a very large long, e.g. 133742007812331115643627009906598839927
for each decrypted value. Trying to use chr()
to convert these to ascii obviously fails with a OverflowError: Python int too large to convert to C long
error.
My plaintext that I am encrypting: this is a test!
The resulting encrypted value(screenshot to preserve special chars):
The hexdump value of the encrypted file:
hexdump -C test.enc
00000000 36 eb 43 3d 1d 0d 68 50 3e b7 7b c0 0e 33 52 12 |6.C=..hP>.
{..3R.|
00000010
My code:
def testdecrypt():
a = 16
e = 65537
p = 15308793451280999927
n = 225614505179301198794693425143200819953
q = 14737575883906276439
phi = (p-1)*(q-1)
d = multiplicative_inverse(e, phi)
with open('test.enc', 'rb') as file:
input = file.read()
print('input as read from file: {0}'.format(input))
input = binascii.hexlify(input)
input = input.replace('\n', '').replace('\r', '')
m = [hex(pow(int(input[i:i+a], 16), d, n)).rstrip("L") for i in range(0, len(input), a)]
print(m)
for mm in m:
str = []
mm = mm.strip('0x')
for i in range(0, len(mm), 2):
mm_chr = chr(int(mm[i:i+2], 16))
str.append(mm_chr) #put in a list for easier viewing
print(str)
Which produces the following output:
input as read from file: 6ëC=
hP>·{À3R
input in hex: 36eb433d1d0d68503eb77bc00e335212
133742007812331115643627009906598839927
73331587639103218432501997963763741611
... 14 more longs
My question is how am I supposed to convert these long values back to ascii? Or am I supposed to do some sort of translation before the decryption operation which wouldn't leave me with these longs? Note that I have tried reading the file in 64bits at a time, but that leaves me with 2 large longs that I still don't know how to convert.
I have looked at this post quite a bit and believe it probably would have helped me solve my problem if the author hadn't apparently deleted some of their comments. I didn't post this on crypto because it seems to be outside their scope since the issue isn't directly with the cryptography.
EDIT:
I did not see this question when posting (swear i looked). However even after reviewing that question and modifying my code to break the decryption into 64-bit chunks I am still left with two hex values, which when converted to ascii using chr()
do not equal the original plain text:
['0x4e4b0c3d7b0f232461adcc78364fef76', '0x652ac1281861415bf4d157947791b419']
['N', 'K', '\x0c', '=', '{', '\x0f', '#', '$', 'a', '\xad', '\xcc', 'x', '6', 'O', '\xef', 'v']
['e', '*', '\xc1', '(', '\x18', 'a', 'A', '[', '\xf4', '\xd1', 'W', '\x94', 'w', '\x91', '\xb4', '\x19']