将解密的RSA值转换为字符串 [英] Convert decrypted RSA value to string

查看:769
本文介绍了将解密的RSA值转换为字符串的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试为我计划的CTF构建模块。这个想法是给您一个加密的文件和一个RSA公钥,并且必须解密该文件。

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.

我有意使用一个较弱的RSA密钥(128位),以便可以对其进行分解并推导出私有指数。我正在使用 -open 填充选项使用 openssl rsautl 加密文件,如下所示:

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.

在我的代码中,我读取了加密文件,将其转换为十六进制,然后对每个十六进制值执行解密操作。这给我留下了很大的长,例如 133742007812331115643627009906598839927 。尝试使用 chr()将其转换为ascii显然会失败,并出现 OverflowError:Python int太大而无法转换为C long 错误。

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.

我正在加密的明文:这是一个测试!

生成的加密值(保留特殊字符的屏幕快照):

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

我的代码:

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)

哪个产生f输出如下:

input as read from file: 6ëC=
hP>·{À3R
input in hex: 36eb433d1d0d68503eb77bc00e335212
133742007812331115643627009906598839927
73331587639103218432501997963763741611
... 14 more longs



<我的问题是我应该如何将这些长值转换回ascii?还是我应该在解密操作之前进行某种翻译,而这不会让我有那么长的时间?请注意,我曾尝试一次以64位读取文件,但是这给了我2个很大的long,但我仍然不知道如何转换。

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.

编辑:

我没有看到这个问题(发誓我看过)。但是,即使在审查了该问题并修改了我的代码以将解密分为64位块之后,我仍然留下两个十六进制值,当使用 chr()将其转换为ascii时不等于原始纯文本:

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']


推荐答案

您应该只跳过该部分十六进制是密文的文本表示(以字节为单位),但是,您只需要字节,而不是人类可读的表示即可。

You should simply skip the part where you convert to hexadecimals. Hexadecimals are an textual representation of the ciphertext in bytes. However, you just need the bytes, not the human readable representation.

要转换为纯文本,您需要一个名为I2OSP的函数:Integer to Octet String Primitive,该函数将纯文本简单地转换为num ber到与密钥大小相同的字节数组-即RSA的模数大小。 RSA使用大端格式的无符号数字。

To convert to plaintext you need a function called I2OSP: Integer to Octet String Primitive, which simply converts the plaintext as number to a byte array of the same size as the key size - i.e. the size of the modulus for RSA. RSA uses unsigned numbers in the big endian format.

之后,您需要将字节解码为ASCII字符串并打印结果。

After that you need to decode the bytes as ASCII string and print the result.

这篇关于将解密的RSA值转换为字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆