我正在尝试实施RSA。但是我有一些问题。我正在尝试用2个质数加密一个字符串。
p= 1606938044258990275541962092341162602522202993782792835301611
q= 3213876088517980551083924184682325205044405987565585670603103
首先,我要做RSA算法必须做的事情。对字符串进行加密后,我也尝试对其进行解密。但是结果是这样的:ÜŞϟʐͶz̽ć
def xgcd(a, b):
"""return (g, x, y) such that a*x + b*y = g = gcd(a, b)"""
x0, x1, y0, y1 = 0, 1, 1, 0
while a != 0:
q, b, a = b // a, a, b % a
y0, y1 = y1, y0 - q * y1
x0, x1 = x1, x0 - q * x1
return b, x0, y0
def genKeypair(p, q):
n = p * q
phiN = (p - 1) * (q - 1)
e = 65537
d = egcd(phiN, e)
return n, e, d
# encrypt message and return cipher
def encrypt(m, n, e):
m1 = ""
# Turn message string into ascii so it can be used for encryption
for x in range(len(m)):
m1 += '{0:03}'.format(ord(m[x]))
# encrypt
c = squareAndMultiply(int(m1), e, n)
print(c)
return c
# decrypt cipher and return message
def decrypt(c, n, d):
# decrypt c
m = squareAndMultiply(c, d, n) #% n
# put decryption result into ascii format and use ascii to decode it
m = str(m)
tmp = ""
message = ""
i = 0
if int(m[0] + m[1] + m[3]) > 255:
m = "0" + m
for x in range(len(m)):
tmp = tmp + m[x]
i += 1
if i % 3 == 0:
message += chr(int(tmp))
tmp = ""
return message
我的平方和乘法方法如下:
def squareAndMultiply(x, n, m=0):
# turn exponent into binary
bin = '{0:b}'.format(n)
r = x
# loop through the string representing the binary form of the exponent while ignoring the leftmost bit and perform
# the appropriate operations on r
for i in range(1, len(bin)):
if (bin[i] == "0"):
r *= r % m
else:
r *= r % m
r *= x % m
# check for m being greater than 0, ignore it otherwise
if (m > 0):
return r % m
else:
return r
有人知道解密可能会带来什么问题以及必须更改哪些内容吗?
答案 0 :(得分:0)
在代码中,通过对每个字符使用相应的十进制 ASCII码(格式为三位数)将明文编码为字符串。
ABCDEF -> 065066067068069070
然后,字符串被转换为整数m
,该整数用作消息并根据
此概念导致m
随着明文长度的增加而越来越大。在某些时候 m
违反了条件m < n
,并且算法失败了(请参见RSA, Operation)!
算法失败的明文长度取决于n
,可以如下确定:在示例中,n
是一个121
数字。由于121/3 = 40.33...
,最多可以加密40
个字符,而不会违反条件m < n
,即从incl。 41
加密通常会失败。可以使用以下代码进行验证:
p = 1606938044258990275541962092341162602522202993782792835301611
q = 3213876088517980551083924184682325205044405987565585670603103
n = p * q
phiN = (p - 1) * (q - 1)
e = 65537
d = egcd(phiN, e)[2]
encrypted = encrypt('0123456789012345678901234567890123456789', n, e); # will succeed
#encrypted = encrypt('01234567890123456789012345678901234567890', n, e); # will fail
decrypted = decrypt(encrypted, n, d);
print('>' + decrypted + '<')
此问题的可能解决方案是将纯文本分成具有相同字符数的块(最后一个块通常包含较少的字符)。该数字应与最大可能的字符数相对应,以便不违反条件m < n
(在发布的示例中== 40
)。然后,每个块分别进行编码和加密(与以前相同)。