2017-04-02 148 views
0

我(还)我的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”返回['72101', '10810', '81113', '28711', '11141', '08100', '32330']clear_list然后 '3863 111 1616 3015 1202 341 4096' as encrypted_message

说明:主程序中调用的函数为encrypt()。它使用另一个函数将字符串转换为unicode值的列表,但是因为我已经读过,因此只能通过频率分析才能找到明确的消息。

真的那么容易吗?

因为它可能是,我来我的主要问题。如你所知,一个字符的Unicode值是两位数或三位数字。在加密之前,Unicode值被分成5个数字组('stack' - >'115 116 97 99 107' - >'11511 69799 10700')

但问题是,当我想解密这个,我怎么知道我必须将那个字符串分开,以便一个数字代表一个字符? 我的意思是,以前的Unicode值可能是11或115(我知道它不可能是11,但这只是一个例子)。所以要解密然后找回角色,问题是,我不知道我需要多少数字。

我原本以为加入了“0”时的Unicode值是< 100,但 1),然后可以很容易地做同样的事情比以前用的频率分析 2)但是,当我进行加密,“ 087'会导致'467'和'089'会导致'046',所以问题仍然存在。

感谢您的帮助,这将是非常赞赏

+1

请不要用RSA加密任意长的数据。 RSA只能以块加密长数据,但RSA并非[意指](http://crypto.stackexchange.com/q/14/13022)可用作分组密码。相反,数据使用新加密的AES加密。密钥又用RSA加密,因为它很短。这种所谓的[混合加密](https://en.wikipedia.org/wiki/Hybrid_cryptosystem)速度更快,更安全(如果您使用随机化和[已验证的分组加密模式](https://en.wikipedia)。组织/维基/ Block_cipher_mode_of_operation#Authenticated_encryption))。 –

+0

Unicode码点数可以超过3个字符长。 – Wyzard

+0

请参阅我对@Marteen Bodewes的回答 – Guil23

回答

3

你试图用玩具RSA问题来解决真实世界的问题。可以执行频率分析,因为没有使用明文消息的随机填充。需要随机填充以使RSA安全。

对于这种问题,直接使用每个字符的Unicode代码点(一个整数值)作为RSA输入就足够了。然而,RSA只能直接加密[0..N)范围内的值,其中N是模数。如果你输入一个更大的值x,那么值将首先被转换成值x模数N.在这种情况下,信息松散,解密不再是确定性的。

至于密文,只需将其作为由空格分隔的整数值的字符串表示形式,然后拆分它们即可读取它们。这将占用更多空间,但RSA总是有一定的开销。


如果要实现安全的RSA那么请读入PKCS#1标准和提防的时间攻击等。而且,作为Wyzard已经指出的,请使用混合加密(使用除了RSA对称加密) 。

或者使用标准库,现在您了解了RSA如何在原则上工作。

+0

范围[0; N [,N至少有4位数字和Unicode值不超过任何问题3位数字(带有我将要使用的符号)。正如我所说这不是一个专业的项目,但目标仍然是使用RSA(不是图书馆)。 Soo ..我认为我必须尝试,因为你们都用混合密码术说过, – Guil23

+0

是的,但是你的'convertIntoUnicode'使用了5个数字,并且试图结合unicode值,你可能不应该这样做。 –

+0

错误..是的。我将从这一点开始 – Guil23

2

convert_into_unicode功能是不是真的将任何东西“为”的Unicode。假设clear_message是一个Unicode字符串(Python 3中的默认字符串类型,或Python 2中的u''),它已经(自然)已经是Unicode了,并且正在使用一种尴尬的方式将它转换为可以加密的字节序列。如果clear_message是一个字节字符串(Python 2中的默认值,或Python 3中的b''),则所有字符都已适合一个字节,因此整个过程是不必要的。

的确,Unicode字符串需要先编码为字节序列,然后才能对其进行加密。正常的做法是使用编码,例如UTF-8UTF-16。您可以致电clear_message.encode('utf-8')。解密后,您可以将解密后的字节字符串转换回为一个Unicode字符串,其编号为decrypted_bytes.decode('utf-8')

根本不需要convert_into_unicode函数。

+0

utf-8不喜欢重音,而utf-8返回一个奇怪的东西,其中唯一的变化是在每个字母之间添加'\ x00',这是正常吗? – Guil23

+0

“不喜欢”口音?它应该处理他们就好。请注意,它们将在输出中编码为多个字节;正常的不重复的英文字母编码成单个字节。在每个字母之间放置“\ x00”是UTF-16所能做的,而不是UTF-8。 – Wyzard

+0

不喜欢,因为它只为一个口音放了很多字符,但也许是正常的。你说得对,第二个'utf-8'是utf-16 – Guil23