这段代码是否会为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
在数学上,你的n,e和d似乎遵守RSA规则(即对于除n的每个素数r,r 2不除n,d是e modulo r-1的倒数).但是,RSA不止于此; 它还强制要求一些填充规则,这些规则控制如何将消息(字节序列)转换为整数模n,然后返回.标准填充(参见PKCS#1)意味着消息中至少添加了11个字节,结果必须不再是n.因此,对于与您显示的模数类似的128位模数,加密的最大输入消息长度将为5个字节.
此外,一些RSA实现将拒绝使用RSA密钥,这些密钥对于安全性而言太小.128位模数可以在几秒钟内完成(请参阅此页面了解分解Java小程序,它使用ECM和二次筛分来计算相对较小的数字,例如你的数字).分解中的当前记录是768位; 建议模数长度至少为1024位,以保证短期安全.典型的RSA实现将接受使用512位密钥,但许多将拒绝任何短于此的密钥.
另一个可能的问题是p和q的相对顺序.在PKCS#1中布置的等式假设p> q(否则,在CRT部分中执行额外的减法).如果你有p ,那么一些实现可能会出错(我在Windows中遇到了微软的RSA标准实现).只需将p与q进行比较,并在必要时进行交换.
仍然在实用性水平上,一些广泛的RSA实现将拒绝RSA密钥,使得公共指数e不适合32位整数(这包括Windows中使用的RSA实现,特别是通过Internet Explorer连接到HTTPS Web网站 - 所以当我写"普遍"时我的意思是).RSA安全性似乎不受e的选择影响,因此习惯上选择小e,这会加速使用公钥的部分(即加密,而不是解密或签名验证,而不是签名代).e = 3是你可以做的最好的,但由于传统的原因(包括对所谓的弱点的历史误解),经常使用e = 65537.你只需要拥有è相对素P-1和Q-1 .在实际实现中,您首先选择e,然后在p和q的生成内循环,只要它们与该附加规则不匹配即可.
从安全角度来看:
你的生成过程并不统一,因为一些主要整数将比其他整数更频繁地被选中.特别地,一个素p,使得P + 2也素几乎从来不会被选择.具有适当的模数大小,这应该不是一个问题(研究了特殊的偏见并发现它不是一个大问题),但它仍然是糟糕的公共关系.
你ñ可能比你的目标尺寸小一点,在情况下,两个p和q接近下限他们那一代的范围.一个简单的方法,以避免是限制的范围内[SQRT(2)*2 B-1,2 b ]两个p和q.
我无法保证random
您使用的模块的安全性.一个加密安全随机数生成器并不是一件容易的事.
一般来说,正确实施RSA而不会通过各种侧通道泄漏机密信息(定时,缓存内存使用......)并非易事.如果您想在实际设置中获得安全性,那么您应该真正使用现有的包.我相信Python有办法与OpenSSL接口.
我假设你这样做是为了娱乐和学习,而不是为了需要实际安全性的东西.
这是我注意到的一些事情(没有特别的顺序):
你无法保证n有长度bits
.它可能短得多bits - 4
.
random
不是加密安全的随机数生成器.
选择公共指数通常(并且同样安全)为e
65537.这是一个素数,因此您可以用除数检查替换互质检查.
e
设置搜索有点奇怪e = tot
(互质检查一定会失败).
否则它看起来很好.关键似乎也很好.你有一个没有正确解密的块的例子吗?请记住,您只能加密小于的数据n
.因此,使用128位密钥(如您所示),您无法加密所有128位数字.