我在Hacker News的this commit中看到了SaltStack,但我并不确切地知道它的作用或原始版本为何会出现加密错误。 (我也不太了解密码学的具体细节如何工作。)
- gen = RSA.gen_key(keysize, 1, callback=lambda x, y, z: None)
+ gen = RSA.gen_key(keysize, 65537, callback=lambda x, y, z: None)
有人可以详细解释为什么选择“1”被替换了吗?为什么“65537”更好?
答案 0 :(得分:64)
你基本上问了三个问题:
1
不好?65537
?听起来你没有很多加密背景,所以我也会尝试填补其中的一些空白。
要理解为什么1
的原始值是一个破碎的选择,您必须了解RSA的工作原理。
RSA是密码系统 - 一种执行密钥生成,加密和解密的方式 - 这样您就可以安全地将消息发送给其他人。 RSA是名为 公钥密码系统 的类的成员,因为用于加密邮件的密钥是 public 强>可以被大家自由地知道。用于解密使用公钥加密的邮件的密钥是秘密的,只有您自己知道,因此我们将其称为 私钥 。
如果您将挂锁和钥匙想象为公钥和私钥的模拟,您可以看到这可能如何与真实世界的消息一起使用:
要实际生成密钥,RSA需要三个重要数字:
RSA的很大一部分安全性来自这样一个事实:鉴于d
和N
,e
应该很难找出<N,e>
。 RSA中的公钥由两个数字组成:<N,d>
,而私钥为1
。
换句话说,如果我知道鲍勃的挂锁是什么样的,那么应该非常困难来反向设计一个可以打开鲍勃挂锁的钥匙。
1
不好? def gen_keys(keydir, keyname, keysize, user=None):
# Generate a keypair for use with salt
# ...
gen = RSA.gen_key(keysize, 1, callback=lambda x, y, z: None)
是一个糟糕的选择,因为它会使非常容易对可以打开Bob挂锁的密钥进行反向工程,这与我们想要的相反。
完整有问题的部分如下所示:
e = 1
这是一个Python片段,它使用N
生成一个RSA密钥。
e
,d
和d*e = 1 mod (p-1)(q-1)
之间的关系由:
e = 1
但是等一下:如果你选择d = 1 mod (p-1)(q-1)
,就像SaltStack那样,那你就有问题了:
d
现在你有了私钥!安全性被破坏,因为您可以找出m
是什么。所以你可以解密每个人的传输 - 你已经做到这一点,以便你可以通过挂锁轻松获得Bob的钥匙。糟糕。
实际上比这更糟糕。在RSA中,加密意味着您有一条消息<N,e>
要使用公钥c
传输您要加密的消息。加密消息 c = m^e (mod N)
计算如下:
e = 1
所以,如果是m^e = m
,那么c = m mod N
,你有m < N
。
但是如果m mod N
,那么m
就是 c = m
。所以你有:
1
加密文本与消息文本相同,因此根本不会发生加密! Double oops。
希望明确为什么65537
是一个糟糕的选择!
e = 3
更好? 65537似乎是一个不寻常的,随意的选择。你可能想知道为什么,例如,我们不能只选择e
。较低的 c = m^e (mod N)
是加密速度加快,因为加密我们必须执行的任何事情:
m^e
,当e
很大时,e = 3
可能是一个非常大的数字。
事实证明,65537主要是出于与现有硬件和软件兼容的原因,以及其他一些原因。 This Cryptography StackExchange answer详细解释了这一点。
使用合适的随机填充方案,您可以选择几乎任何高于1的奇数,而不会影响安全性,因此{{1}}是最大化性能的选择。