如何解密用 RSA 加密的块?
How to decrypt blocks encrypted with RSA?
我还在做我的 RSA 项目,现在我可以成功创建密钥,并用它们加密字符串
def encrypt(clear_message, public_key):
clear_list = convert_into_unicode (clear_message)
n = public_key[0]
e = public_key[1]
message_chiffre = str()
for i, value in enumerate (clear_list) :
encrypted_value = str( pow (int(value), e, n) )
encrypted_message += (encrypted_value )
return encrypted_message
def convert_into_unicode (clear_message):
str_unicode = ''
for car in clear_message:
str_unicode += str (ord (car))
if len (str_unicode ) % 5 != 0:
str_unicode += (5 - len (str_unicode ) % 5) * '0'
clear_list = []
i = 5
while i <= len (str_unicode ):
clear_list .append (str_unicode [i-5:i])
i += 5
return liste_claire
例如,将消息 'Hello World'
returns ['72101', '10810', '81113', '28711', '11141', '08100', '32330']
加密为 clear_list
然后
'3863 111 1616 3015 1202 341 4096'
作为 encrypted_message
encrypt ()
函数使用另一个函数将字符串转换为 Unicode 值列表,但放入块中,因为我已经阅读过,否则,很容易找到明确的消息频率分析。
真的那么容易吗?
很可能,我来谈谈我的主要问题。如您所知,字符的 Unicode 值要么是两位数,要么是三位数。在加密之前,Unicode 值被分成 5 位数字的块 ('stack' -> '115 116 97 99 107' -> '11511 69799 10700')
但问题是当我想解密它时,我怎么知道我必须在哪里分隔该字符串以便一个数字代表一个字符?
我的意思是,以前的 Unicode 值可以是 11 或 115(我知道它不可能真的是 11,但这只是作为示例)。所以要解密然后取回字符,问题是,我不知道我要取多少位数。
我曾想过在 Unicode 值 < 100 时添加一个 0
,但是
- 然后通过频率分析就可以很容易地做和以前一样的事情了
- 不过,当我加密它时,'087'可能导致'467','089'可能导致'046',所以问题仍然存在。
您的 convert_into_unicode
函数并没有真正转换任何 "into" Unicode。假设 clear_message
是 Unicode 字符串(Python 3 中的默认字符串类型,或 Python 2 中的 u''
),它(自然)已经是 Unicode,并且您正在使用将其转换为可以加密的字节序列的笨拙方法。如果clear_message
是一个字节串(Python2中默认,或者Python3中b''
),所有的字符都已经在一个字节中了,所以整个过程是没必要。
Unicode 字符串确实需要先编码为字节序列,然后才能对其进行加密。正常的做法是使用 UTF-8 or UTF-16 这样的编码。您可以通过调用 clear_message.encode('utf-8')
来做到这一点。解密后,可以将解密后的字节串转回Unicode串decrypted_bytes.decode('utf-8')
.
您根本不需要 convert_into_unicode
函数。
您正在尝试用玩具 RSA 问题解决现实世界中的问题。可以执行频率分析,因为没有使用明文消息的随机填充。需要随机填充以使 RSA 安全。
对于此类问题,直接使用每个字符的Unicode代码点(整数值)作为RSA的输入就足够了。然而,RSA 只能直接加密 [0..N) 范围内的值,其中 N 是模数。如果你输入一个更大的值 x 然后值将首先转换为值 x 模数 N。在这种情况下你丢失信息并且解密将不再是确定性的。
至于密文,只需将其作为由space分隔的整数值的字符串表示并将它们拆分以读取它们。这将需要更多space,但RSA总是有一定的开销。
如果您想实施安全的 RSA,请阅读 PKCS#1 标准并提防时间攻击等。并且,正如 Wyzard 已经指出的那样,请使用混合密码术(除了 RSA 之外还使用对称加密)。
或者使用标准库,现在你明白RSA的原理了。
我还在做我的 RSA 项目,现在我可以成功创建密钥,并用它们加密字符串
def encrypt(clear_message, public_key):
clear_list = convert_into_unicode (clear_message)
n = public_key[0]
e = public_key[1]
message_chiffre = str()
for i, value in enumerate (clear_list) :
encrypted_value = str( pow (int(value), e, n) )
encrypted_message += (encrypted_value )
return encrypted_message
def convert_into_unicode (clear_message):
str_unicode = ''
for car in clear_message:
str_unicode += str (ord (car))
if len (str_unicode ) % 5 != 0:
str_unicode += (5 - len (str_unicode ) % 5) * '0'
clear_list = []
i = 5
while i <= len (str_unicode ):
clear_list .append (str_unicode [i-5:i])
i += 5
return liste_claire
例如,将消息 'Hello World'
returns ['72101', '10810', '81113', '28711', '11141', '08100', '32330']
加密为 clear_list
然后
'3863 111 1616 3015 1202 341 4096'
作为 encrypted_message
encrypt ()
函数使用另一个函数将字符串转换为 Unicode 值列表,但放入块中,因为我已经阅读过,否则,很容易找到明确的消息频率分析。
真的那么容易吗?
很可能,我来谈谈我的主要问题。如您所知,字符的 Unicode 值要么是两位数,要么是三位数。在加密之前,Unicode 值被分成 5 位数字的块 ('stack' -> '115 116 97 99 107' -> '11511 69799 10700')
但问题是当我想解密它时,我怎么知道我必须在哪里分隔该字符串以便一个数字代表一个字符?
我的意思是,以前的 Unicode 值可以是 11 或 115(我知道它不可能真的是 11,但这只是作为示例)。所以要解密然后取回字符,问题是,我不知道我要取多少位数。
我曾想过在 Unicode 值 < 100 时添加一个 0
,但是
- 然后通过频率分析就可以很容易地做和以前一样的事情了
- 不过,当我加密它时,'087'可能导致'467','089'可能导致'046',所以问题仍然存在。
您的 convert_into_unicode
函数并没有真正转换任何 "into" Unicode。假设 clear_message
是 Unicode 字符串(Python 3 中的默认字符串类型,或 Python 2 中的 u''
),它(自然)已经是 Unicode,并且您正在使用将其转换为可以加密的字节序列的笨拙方法。如果clear_message
是一个字节串(Python2中默认,或者Python3中b''
),所有的字符都已经在一个字节中了,所以整个过程是没必要。
Unicode 字符串确实需要先编码为字节序列,然后才能对其进行加密。正常的做法是使用 UTF-8 or UTF-16 这样的编码。您可以通过调用 clear_message.encode('utf-8')
来做到这一点。解密后,可以将解密后的字节串转回Unicode串decrypted_bytes.decode('utf-8')
.
您根本不需要 convert_into_unicode
函数。
您正在尝试用玩具 RSA 问题解决现实世界中的问题。可以执行频率分析,因为没有使用明文消息的随机填充。需要随机填充以使 RSA 安全。
对于此类问题,直接使用每个字符的Unicode代码点(整数值)作为RSA的输入就足够了。然而,RSA 只能直接加密 [0..N) 范围内的值,其中 N 是模数。如果你输入一个更大的值 x 然后值将首先转换为值 x 模数 N。在这种情况下你丢失信息并且解密将不再是确定性的。
至于密文,只需将其作为由space分隔的整数值的字符串表示并将它们拆分以读取它们。这将需要更多space,但RSA总是有一定的开销。
如果您想实施安全的 RSA,请阅读 PKCS#1 标准并提防时间攻击等。并且,正如 Wyzard 已经指出的那样,请使用混合密码术(除了 RSA 之外还使用对称加密)。
或者使用标准库,现在你明白RSA的原理了。