公众号旧文
为什么公钥能验证私钥,却无法推导出私钥?
最近在探索 SSH 免密登录的原理。
很快就产生了一个疑问:
既然公钥能够验证私钥生成的签名,
那为什么不能反过来,根据公钥把私钥算出来呢?
这听起来似乎有点矛盾,但实际上,一点儿也不矛盾。
因为验证和推导根本不是同一件事情。
一、先举个简单例子
想象有一道数学题:
13 × 17 = 221
显然,答案是 221。
如果想要验证 13 和 17 相乘是不是等于 221
我们只需要计算一次 13 × 17 马上就知道答案。
非常容易。
但如果我只告诉你答案是 221
然后问你:221 是由哪两个质数相乘得到的?
难度立刻上升。
你得不断尝试:
221 ÷ 2
221 ÷ 3
221 ÷ 5
221 ÷ 7
...
最后才发现:
221 = 13 × 17
这就是密码学里最核心的思想:
正向计算容易,逆向求解困难。
二、公钥密码也是同样的逻辑
以 RSA 为例。
生成密钥时会先随机选择两个超大的质数:
p
q
然后计算:
n = p × q
这个 n 会被放进公钥中。
例如:
公钥:
(n, e)
私钥则包含:
d
以及与 p、q 有关的重要信息。
三、为什么公钥可以公开?
因为别人即使拿到了 n
也只知道 n = p × q
但不知道 p 是多少,q 是多少
如果 p 和 q 只有两位数。
当然很容易算出来。
但现实中 p 和 q 往往有几百位数字,甚至更长。
此时想把 n 分解回去:
n → p × q
会变得极其困难。
这就是著名的大整数分解难题。
四、验证为什么反而容易?
因为验证签名并不是根据公钥推出私钥,
而是检查这个签名是否符合数学规则。
就像考试一样。
老师批改试卷时,并不需要重新参加考试,只需要检查答案是否正确。
RSA 签名也是类似过程。
私钥生成签名:
消息
↓
私钥运算
↓
签名
验证时:
签名
↓
公钥运算
↓
检查结果
如果结果符合预期,就验证通过,否则验证失败
整个过程中,公钥只是负责检查。
它并没有获得足够的信息去反推出私钥。
五、一个生活中的比喻
把私钥想象成一枚印章。
公钥则是一张印章样本。
你拿着印章,盖章,生成文件。
别人拿着样本,对比,确认这是不是同一枚章盖出来的。
因此别人能够验证这确实是你的印章盖的,
但并不能根据盖出来的印记直接造出一枚完全相同的印章。
验证是真伪鉴定。
伪造则是重新制造。
两者完全不是一个难度级别。