RSA加密/解密:转换为字符串

时间:2017-02-15 22:51:57

标签: python encryption rsa

我正在为我的一个班级做一个项目。教授让我们在不使用加密库的情况下制作RSA加密/解密程序(全部从头开始)。所以我得到了我的p,q,n,phi,e和d,一切都很好。我遇到的问题是尝试加密它。我采用每个字符的ASCII条例并使用我的e和n加密。但是,我回来的数字远远超出范围,可以更改为ASCII字符。如何将该数字更改为字符,以后仍然可以使用我的私钥解密它?这是我到目前为止的粗略代码:

import random

def generatePrimes():
    prime = False
    while prime == False:
        n = random.randint(10000, 100000) #generates random integer between 10,000 and 100,000
        if n % 2 != 0: #checks if integer is divisible by 2
            for x in range(3, int(n ** 0.5), 2): #starts at 3, increments by 2 to check if integer is divisible by anything
                if n % x == 0:
                    break #if integer divides a number x and  has no remainder, it isn't prime and the loop breaks
                else:
                    prime = True #a prime number is found

    return n #returns prime number



def  findE(n, pn):
    factor = True
    while factor == True:
        e = random.randint(3, 35) #creates random integer from 2 to p(n), but keeps it small for ease of use
        if n % e != 0: #checks if integer is divisible by n
            factor = False #if remainder is not 0, the integer isn't divisible by n. if remainer is 0, the loop restarts to choose another number

     return e



def findD(e, pn):
    d = pow(e, pn - 2, pn) #calculates d

    return d



def encryption():
    p = generatePrimes() #creates random prime number for p
    q = generatePrimes() #creates random prime number for q
    n = p * q #finds n by multiplying p and q
    pn = (p - 1) * (q - 1) #finds p(n)
    e = findE(n, pn) #creates e such that 1 < e < p(n)
    d = findD(e, pn) #creates d

    print('n =', n)
    print('e =', e)
    print('d =', d)

    print('Keys have been created.')
    message = input('Enter the message you wish to encrypt:')

    newMessage = '' #creates new string that the encrypted message will be put into
    for x in message:
        x = ord(x) #converts character into ASCII reference number
        x = (x ** e) % n #encrypts using rsa algorithm
        x = chr(x)
        newMessage += x #places new character into the encrypted string

    print('Here is your encrypted message:')
    print(newMessage) 


def decryption():
    n = int(input('Enter in a value for n:'))
    d = int(input('Enter in a value for d:'))

    newMessage = []
    message = input('Enter the message you wish to decrypt:')
    for x in message:
        x = ord(x)
        x = (x ** d) % n
        x = chr(x)
    newMessage += x

    print('Here is your decrypted message:')
    print(newMessage)

2 个答案:

答案 0 :(得分:2)

通常,对于这种玩具RSA实现,每个字符都是单独加密的。现在加密将导致零和N之间的值,即模数。

对此值进行编码的最简单方法可能是始终确保它的大小为小数,其中dLen是显示模数N所需的小数位数。您可以通过在数字前加零数字来实现此目的。合适的尺码。然后,要解密,读取dLen字符,将其转换为数字,然后使用私钥执行模幂运算。

对于实际的RSA加密(例如RSA-OAEP)也会发生同样的事情。这里加密的结果被转换为保持模数所需的相同数量的字节。此功能称为I2OSP。上面的实现将让你练习实现这样的功能。

当Tamas解释说 - 在现实生活中 - 这不是如何加密字符串时,当然是正确的。您使用混合密码系统而不是块密码加密明文(转换为字节)。

答案 1 :(得分:1)

您不能单独加密字符串中的每个字符。您必须将整个字符串编码为单个数字,并对该数字执行rsa加密。在解码时必须反向完成相同的操作。 RSA有标准字符序列可以有多长,它应该如何编码和填充。 (见PKCS1或OAEP)

您的findE功能有缺陷。没有人关心n%e==0,但epn必须是互质的。最简单的方法是为e e==65537选择一个不太小的素数。它不一定是随机的。