RSA python 加密

问题描述 投票:0回答:2

(对于学校)我正在尝试进行简单的 RSA 加密,将字符串加密为三个字母的块。 我可以更改什么以使数学能够使用字符串而不仅仅是整数?

import math

message = str(input("Enter Plaintext: "))

p = 521
q = 757
e = 11
n = p*q

def encrypt(me):
    en = math.pow(me, e)
    c = en % n
    print("Encrypted Message is: ", c)
    return c

print("Original Message is: ", message)
c = encrypt(message)
Enter Plaintext: zallaboardty
Original Message is:  zallaboardty
line 18, in <module>
    c = encrypt(message)
line 11, in encrypt
    en = math.pow(me, e)
TypeError: must be real number, not str

Process finished with exit code 1
python encryption rsa
2个回答
0
投票

教科书RSA中的消息大小是由模数的大小决定的。因此,模数 n 为 521 x 757。这允许 log_2(521 x 757) / 3 = 每个字符约 6.19 位。因此每个字符只能占用 6 位,即它的范围是 [0..2^6) = [0..64) 个字符。 ASCII 是每个字符 7 位,所以这有点烦人,因为我们不能直接使用它。

让我们简单一点,用小数来计算。我们可以计算出 n 为 521 x 757 = 394397。这意味着我们可以通过连接三个两位数来构造一个低于 n 的数字,只要该数字低于 394397。如果我们使用 39 或以下的数字,这将始终有效。我们现在可以创建最多 40 个字符的字母表(因为我们可以包含零个字符)。

让我们为包含 ABC 的 28 个字符的字母表定义一个字母表 SPACE=0、A=1...Z=26 和 DOT=27。太好了,现在我们只需首先将消息转换为索引,例如: “你好世界。”可分为“HEL”、“LO”、“WOR”和“LD”。所以你取H=“08”,E=“05”en L=“12”,所以我们得到的数字是“080512”或080512。太好了,你现在有了一个可以由RSA处理的数字。请注意,数字必须在左侧填充零才能使该方案发挥作用。

现在小数使用基数 10。您还可以使用基数 2^6(记住上面每个字符 ~6.19 位)并从二进制创建一个数字。然而,对于初学者来说,使用小数和字符串更容易。


0
投票

如您所知,尝试对字符串而不是数字使用 math.pow 将导致类型错误。要解决此问题,您可以将字符串转换为实数,方法是首先在

encode
(在您的函数中)上使用
me
将其转换为字节,然后使用
int.frombytes
将字节转换为整数。您可以这样做:

me = int.from_bytes(me.encode('utf-8'), byteorder="big")

RSA 没有明确要求使用 UTF-8 或特定的字节顺序(如 big-endian)。这样做只是为了遵循通用标准并确保兼容性,但选择权在您。

另一个小问题是您使用的是 math.pow,这在处理大整数时可能会导致精度错误。相反,您应该使用 pow(内置 Python 函数)采用模幂方法,该方法针对此类操作进行了优化。您更正后的代码将是:

c = pow(me, e, n)

现在,你的函数应该看起来像这样:

def encrypt(me):
    me = int.from_bytes(me.encode('utf-8'), byteorder="big")
    c = pow(me, e, n)
    print("Encrypted Message is: ", c)
    return c
© www.soinside.com 2019 - 2024. All rights reserved.