这是生成rsa密钥的正确方法吗?

时间:2010-05-09 23:01:40

标签: python cryptography rsa public-key

这段代码是否会为RSA密钥提供正确的值(假设其他函数是正确的)?我无法正常解密我的程序,因为某些块没有正确解密

这是在python:

import random
def keygen(bits):
    p = q = 3
    while p == q:
        p = random.randint(2**(bits/2-2),2**(bits/2))
        q = random.randint(2**(bits/2-2),2**(bits/2))
        p += not(p&1)                             # changes the values from 
        q += not(q&1)                             # even to odd

        while MillerRabin(p) == False:            # checks for primality
            p -= 2
        while MillerRabin(q) == False:
            q -= 2
    n = p * q   
    tot = (p-1) * (q-1)
    e = tot
    while gcd(tot,e) != 1:
        e = random.randint(3,tot-1)
    d = getd(tot,e)                       # gets the multiplicative inverse
    while d<0:                            # i can probably replace this with mod
        d = d + tot
    return e,d,n

生成一组密钥:

e = 3daf16a37799d3b2c951c9baab30ad2d

d = 16873c0dd2825b2e8e6c2c68da3a5e25

n = dc2a732d64b83816a99448a2c2077ced

2 个答案:

答案 0 :(得分:16)

在数学上,您的 n e d 似乎遵守RSA规则(即每个素数 r 除以 n r 2 不划分 n d e modulo r-1 的逆矩阵。但是,RSA不止于此;它还强制要求一些填充规则,这些规则控制如何将消息(字节序列)转换为整数模 n ,然后返回。标准填充(请参阅PKCS#1)表示至少有11个字节添加到消息中,结果必须仍然不再是 n 。因此,具有128位模数 与您显示的一样,加密的最大输入消息长度为5个字节。

此外,一些RSA实现将拒绝使用RSA密钥,这些密钥对于安全性而言太小。 128位模数可以在几秒钟内得到(对于分解Java小程序,请参阅this page,它使用ECM和二次筛来计算相对较小的数字,例如你的数量)。分解中的当前记录是768位;建议模数长度至少为1024位,以保证短期安全。典型的RSA实现将接受使用512位密钥,但许多将拒绝任何短于此的东西。

另一个可能的问题是 p q 的相对顺序。在PKCS#1中列出的等式假设 p> q (否则,在CRT部分中执行额外的减法)。如果你有 p&lt; q ,然后一些实现可能会出错(我在Windows中遇到了Microsoft的RSA标准实现)。只需将 p q 进行比较,并在必要时进行交换。

仍然在实用性方面,一些广泛的RSA实现将拒绝RSA密钥,使得公共指数 e 不适合32位整数(这包括Windows中使用的RSA实现,特别是通过Internet Explorer连接到HTTPS网站 - 所以当我写“广泛”时我的意思是)。 RSA安全性似乎没有受到 e 选择的影响,因此习惯上选择一个小的 e ,这会加速使用公钥的部分(即加密,而不是解密或签名验证,而不是签名生成)。 e = 3 是您可以做的最好的事情,但由于传统原因(包括对所谓的弱点的历史误解),经常使用 e = 65537 。您只需要 e p-1 q-1 进行相对处理。在实际实现中,首先选择 e ,然后在 p q 的代中循环,只要它们与该附加规则不匹配即可

从安全角度来看:

  • 您的生成过程并不统一,因为某些素数整数的选择频率会高于其他素数。特别是, p 这样 p + 2 也是素数的几乎永远不会被选中。使用适当的模数大小,这个应该不应该是一个问题(研究了特殊的偏见并发现它不是一个大问题),但它仍然是糟糕的公共关系。

    < / LI>
  • 如果 p q 接近较低值, n 可能会比目标尺寸略小一些他们这一代人的范围。避免这种情况的一种简单方法是将范围限制为 [sqrt(2)* 2 b-1 ,2 b ] em> p 和 q

  • 我无法保证您使用的random模块的安全性。 加密安全随机数生成器并不容易。

  • 一般来说,正确实施RSA而不会通过各种辅助渠道(时间,缓存内存使用......)泄露机密信息并非易事。如果您想在实际设置中获得安全性,那么您应该真正使用现有的包。我相信Python有办法与OpenSSL进行交互。

答案 1 :(得分:5)

我认为你这样做是为了娱乐和学习,而不是为了需要实际安全的东西。

以下是我注意到的一些事情(没有特别的顺序):

  1. 您不能保证n的长度为bits。它可能与bits - 4一样短。

  2. random不是加密安全的随机数生成器。

  3. 选择公共指数e到65537是很常见的(同样安全)。这是一个素数,因此您可以用除数检查替换互质检查。

  4. 通过设置e搜索e = tot有点奇怪(互质检查一定会失败)。

  5. 否则它看起来很好。关键似乎也很好。你有一个没有正确解密的块的例子吗?请记住,您只能加密小于n的数据。因此,使用128位密钥(如您所示),您无法加密所有128位数字。