繁体   English   中英

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

[英]RSA encryption/decryption: converting to string

我正在为一个班级做一个项目。 教授让我们在不使用加密库的情况下制作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)

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

编码此值的最简单方法可能是始终确保其大小为dLen小数,其中dLen是显示模数N所需的小数位数。您可以通过在数字前加上零直到该值大小正确为止。 然后,要解密,请读取dLen字符,将其转换为数字,并使用私钥执行模幂运算。

实际的RSA加密(例如RSA-OAEP)也会发生相同的情况。 此处,加密结果被转换为保持模数所需的相同字节数。 此功能称为I2OSP。 上面的实现将使您练习实现这种功能。


当Tamas解释-在现实生活中-这不是加密字符串的方式时,他当然是正确的。 您将使用混合密码系统,在该系统中,块密码对明文(转换为字节)进行加密。

您不得单独加密字符串中的每个字符。 您必须将整个字符串编码为一个数字,然后对该数字执行rsa加密。 解码时必须反向进行相同的操作。 RSA规定了字符序列可以有多长,应该如何编码和填充。 (请参阅PKCS1或OAEP)

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM