【问题标题】:RSA encryption/decryption: converting to stringRSA加密/解密:转换为字符串
【发布时间】:2017-02-15 22:51:56
【问题描述】:

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

【问题讨论】:

  • 附带说明,编写自己的加密算法在现实世界的应用中是可怕的做法。与回答问题无关,但我只是想帮助理解程序化世界中的良好原则。

标签: python encryption rsa


【解决方案1】:

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

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

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


Tamas 当然是正确的,他解释说——在现实生活中——这不是加密字符串的方式。您将使用混合密码系统,而不是使用分组密码加密明文(转换为字节)。

【讨论】:

  • 当然,只要合适,你也可以把几个字符放在一起。您首先将它们编码为字节(例如使用 ASCII),然后将生成的字节转换为整数。
  • 但是在解密的时候,你如何确定哪个整数对应哪个字母呢?例如。 15 是“o”还是“ae”?
  • 两者都不是。您会期望与x = ord(x) #converts character into ASCII reference number 中的字符值相同(考虑单个字符)。当然你不应该使用x = chr(x),因为这会在加密后丢弃信息。
【解决方案2】:

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

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

【讨论】:

  • 我的教授告诉我们,e 不能是 n 的因数,所以我检查了 n%e==0。我将如何将整个字符串编码为一个数字?
猜你喜欢
  • 1970-01-01
  • 2017-10-31
  • 2023-03-14
  • 1970-01-01
  • 1970-01-01
  • 2014-02-06
  • 1970-01-01
  • 1970-01-01
  • 2013-06-08
相关资源
最近更新 更多