V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
manfred4527
V2EX  ›  问与答

关于公钥 私钥 非对称数字加密 数字签名 和数字证书 原理

  •  1
     
  •   manfred4527 · 2018-06-07 11:33:58 +08:00 · 4700 次点击
    这是一个创建于 2367 天前的主题,其中的信息可能已经有所发展或是发生改变。

    现在对公钥 私钥 非对称数字加密 数字签名 和数字证书理解非常混乱,

    公钥和私钥是成对的吗?一对一 还是一对多的关系?

    数字签名是用私钥加密 公钥解密,如果 A B C 三人的公钥相同 是不是可以直接得到互相的摘要值?这样安全性没有问题吗?

    数字证书一般是服务器发送给客户端的,各个客户端的数字证书是一样的吗?客户端收到的数字证书,里面包含了公钥.那服务器发起的数据加密是用服务器的私钥加密再发送给客户端公钥解密吗?如果这样不是大家都能解密?

    37 条回复    2018-08-09 10:28:35 +08:00
    3dwelcome
        1
    3dwelcome  
       2018-06-07 11:40:59 +08:00   ❤️ 1
    公钥密钥是一对一的关系。只要服务器的密钥不泄漏,客户端用公钥加密的数据,天下就只有一台服务器可以解密,这样就起到了避免第三方伪造服务器的功效。

    然后数字签名保证了公钥是无法被修改的( CA 根证书的签发),所以客户端能识别到正确的服务器,同理,如果服务器需要验证客户端,也可以让客户端给服务器发数字签名证书,确保客户端不会被伪造。
    3dwelcome
        2
    3dwelcome  
       2018-06-07 11:45:01 +08:00
    "如果 A B C 三人的公钥相同 是不是可以直接得到互相的摘要值?"
    就 HTTPS 而言,数据加密不仅仅公钥密钥,那只是握手验证而已。每次一加密都包含了关键的服务器随机数和客户端随机数,所以 C 要冒充 AB,由于客户端随机数无法伪造,每一次服务器随机数也无法伪造,几乎是不可能的。

    所以你最后那句“如果这样不是大家都能解密”,肯定是无法实现的。
    manfred4527
        3
    manfred4527  
    OP
       2018-06-07 11:52:13 +08:00
    @3dwelcome 有些资料写是公钥对私钥可以是一对多的看着就比较纳闷

    说数字签名是一种逆向的非对称加密,如果是一对一的公钥私钥 用私钥加密的话 是不是意味着只有服务器上对应的那一把公钥能解?如果有外人获取到那一把发送的公钥 是不是意味着可以截取到 数字签名信息
    3dwelcome
        4
    3dwelcome  
       2018-06-07 12:00:50 +08:00
    私钥顾名思义,就是不能公开,服务器上一般只能存私钥,而且必须加密保存,不能外泄。

    至于公钥,都是嵌入到数字证书里的,让 CA 做认证,打个包,起名叫.cer 扩展,放到服务器上,任何客户端用 HTTPS 访问的时候,都可以获取证书和公钥。

    所以,数字证书和公钥和签名信息,都是公开给大众访问的。但仅仅靠这点数据,也是没办法黑到别人客户端上的数据的。因为真的数据加密不是用 RSA,而是用 AES 对称式加密。RSA 只是药引,负责生成加密 KEY 而已。
    GuuJiang
        5
    GuuJiang  
       2018-06-07 12:03:15 +08:00
    @manfred4527
    第一个问题,取决于具体的算法,有的算法确实是一个私钥可以导出多个公钥的,这没有什么好疑惑的
    第二个问题,公钥本来就是公开的,数字签名也本来就是公开的,任何人都可以验证
    3dwelcome
        6
    3dwelcome  
       2018-06-07 12:13:22 +08:00
    @GuuJiang "Public-key algorithms such as RSA or ECDSA have exactly one private key for each public key and vice versa."

    “一个私钥可以导出多个公钥的", 有具体出处吗?我网上查到的都是一对一关系啊。
    Miary
        7
    Miary  
       2018-06-07 12:26:23 +08:00 via Android
    这些东西连百度百科都能给你解释清楚。
    glacer
        8
    glacer  
       2018-06-07 12:32:34 +08:00 via iPhone
    复习下计算机网络这本书吧
    WuwuGin
        9
    WuwuGin  
       2018-06-07 12:41:54 +08:00 via Android
    额,首先 pubkey 是 encrypt,privatekey 是 decrypt。
    honeycomb
        10
    honeycomb  
       2018-06-07 12:44:32 +08:00 via Android
    公钥和私钥确实是一对的。

    但实际的封装中,一般私钥文件同时包含私钥与公钥,公钥文件则只包含公钥。

    至于具体的步骤,应该看一下 TLS 协商的流程。
    manfred4527
        11
    manfred4527  
    OP
       2018-06-07 12:57:39 +08:00
    @3dwelcome
    @honeycomb
    谢谢回复

    公钥私钥是一对的,所以我去打开 https 加密网页比如 google ,google 会给我一个数字证书,数字证书里面包含了 goolge 给我的公钥. 所以我电脑中的公钥和别人收到 google 发给他们的数字证书中的公钥是不一样的对吗?
    3dwelcome
        12
    3dwelcome  
       2018-06-07 13:11:37 +08:00 via Android
    你和别人拿到的公钥都是一样的,数字证书的目的,是保护里面关键信息不被第三方篡改,公钥就包含其中。
    keyfunc
        13
    keyfunc  
       2018-06-07 13:25:06 +08:00
    公私钥肯定是 1 对 1 的,请不要把数字证书和公私钥对搞混了。详情可以看下非对称算法的原来,RSA 的很简单。

    另外还有一个概念,公钥加密,私钥解密,私钥签名、公钥验签。

    TLS 加密并不是通过公钥做加密的,TLS 主要还是使用对称加密,公私钥只是协商对称加密的密钥时用,每个会话的密钥都不同的,不存在泄密的问题。
    blackjar
        14
    blackjar  
       2018-06-07 13:44:35 +08:00
    @3dwelcome #4 rsa 是用来做 key exchage 的 什么时候“负责生成加密 KEY ”了?
    GuuJiang
        15
    GuuJiang  
       2018-06-07 14:03:21 +08:00
    @3dwelcome 嗯,收回我前面的错误说法,确实应该是一对一的,是我把多个比特币钱包地址那一套记混了
    3dwelcome
        16
    3dwelcome  
       2018-06-07 14:17:47 +08:00
    @blackjar HTTPS 里面握手关键的一步叫 CLIENT_KEY_EXCHANGE,就是把双方约定的 preMasterSecret,变成真正加密的 MasterSecret,这步就是需要 RSA 参与计算的。

    而 MasterSecret 就是用于加密数据的 key,这段数据非常关键,所以并不能直接在网络上传输,需要服务器和客户端做约定,先用客户端 /服务器随机数,填充 preMasterSecret,然后用 RSA 来加密 /解密,相当于生成最终 KEY 了。

    而由于 MasterSecret 非常重要,有些移动客户端为了服务器性能考虑(ssl resume ticket),把 MasterSecret 缓存在本地磁盘,最终导致了把 HTTPS 安全直接降级到了 HTTP,是需要鄙视的。
    manfred4527
        17
    manfred4527  
    OP
       2018-06-07 14:30:23 +08:00
    @3dwelcome 如果我和别人的公钥是一样的话,那在服务器上的私钥是不是也一样的? 如果不一样 那不是一个公钥 对应多个私钥的情况
    如果公钥私钥都一样 那不是没有安全意义了.
    3dwelcome
        18
    3dwelcome  
       2018-06-07 14:37:49 +08:00
    @manfred4527 其实你还是没有仔细看回复,随机数这个概念很重要。

    虽然公钥密钥大家都一样,但机器不一样,时间不一样,生成的随机数不一样。所以每一次最终参与时间加密的 KEY,是截然不一样的。

    如果你没有办法获取别人的 KEY,那你就没办法解密和监视别人传输的数据内容。这样 HTTPS 的数据流就是安全的。
    3dwelcome
        19
    3dwelcome  
       2018-06-07 14:46:32 +08:00
    如果 HTTPS 的文本内容是 RSA 直接加密 /解密的,那么你说公钥一致私钥一致,解密的数据就是一致的。但可惜 HTTPS 不是这样运作的,加密都是对称式加密,RSA 只对 KEY 负责。

    举个例子,你客户端生成了一个随机数 250,用 RSA 公钥加密了,发给服务器。然后服务器用 RSA 私钥还原,计算得出 master key,用于数据加密。

    你作为第三方偷窥者,是无法用 RSA 公钥,来还原出客户端随机数 250。得不到 250,你就没办法填充 permasterkey,没办法填充 permasterkey,就没办法导出最终的 master key。都是一个萝卜一个坑,中间少了任何一个环节,加密结果就差很多。
    minyress
        20
    minyress  
       2018-06-07 15:00:24 +08:00
    manfred4527
        21
    manfred4527  
    OP
       2018-06-07 15:02:20 +08:00
    @3dwelcome
    我感觉我概念又混乱了 请大佬帮忙解答一下 谢谢
    我之前提到一个问题的结论
    1.公钥私钥是成对的

    我之后问了一个问题就是我们浏览网页 收到的数字证书上有一个公钥是负责加密的(一般都是 RSA) 大家电脑上的这个公钥是不是都是不一样的 大佬你的回答是都一样的
    所以按我的理解 因为公钥私钥是成对的 所以大家在服务器上的私钥也是一样的

    你说主要传输用对称算法 比如 AES 这种 , 非对称只是为了传输 对称的 KEY 就是你说的随机数.
    那按我的理解 如果在数字证书这一步

    "举个例子,你客户端生成了一个随机数 250,用 RSA 公钥加密了,发给服务器。然后服务器用 RSA 私钥还原,计算得出 master key,用于数据加密。 "

    我对 250 这个随机数加密是和别人用同样的公钥 ,服务器上的私钥也是一样的.是不是意味着 大家的加密方式(算法和公钥一样的) 解密方式也是一样的,只是我们大家的私钥虽然一样.但是这个私钥在服务器上,我们大家都没法得到私钥,所以传输这个 随机数的 KEY 是安全的..

    是这么理解吗?
    deadEgg
        22
    deadEgg  
       2018-06-07 15:07:20 +08:00
    @GuuJiang 请问什么非对称加密算法一个私钥可以对应多个公钥?
    deadEgg
        23
    deadEgg  
       2018-06-07 15:07:43 +08:00
    @GuuJiang 才看到纠正。。sorry。
    3dwelcome
        24
    3dwelcome  
       2018-06-07 15:10:58 +08:00   ❤️ 1
    @manfred4527

    是的,终于理解了,理解万岁。

    PS:进度条快结束了,攒满后就没办法回贴了。哎,要是 V2EX 的进度条能升级就好了-_-
    hatcloud
        25
    hatcloud  
       2018-06-07 15:18:11 +08:00
    @manfred4527 #11 看一下 RSA 吧
    msg7086
        26
    msg7086  
       2018-06-08 03:17:31 +08:00
    RSA 生成密钥这个也已经淘汰了吧。
    现在主流都是 DHE 或者 ECDHE。(迪菲-赫尔曼密钥交换)
    甲有一个秘密随机数 a,乙有一个秘密随机数 b,然后通过一顿黑科技骚操作,让甲能得知 b,乙能得知 a,而不被第三方得到 a 和 b 的具体数字。有了 a 和 b 以后,再得到密钥 s,作为对称加密密钥。
    这种密钥交换的好处是不需要事先传送公钥,以及完备向前安全性(即窃听者以后若能破解这种密钥交换,也无法回过头破解过去的加密通信数据)。
    DHE 还有个好处就是速度比 RSA 快得多。

    现代浏览器一般用这样的:
    ECDHE-ECDSA-CHACHA20-POLY1305
    其中 ECDHE 负责密钥交换,ECDSA 负责证书签名认证,擦擦玻璃负责加密和完整性验证。
    当然还有用 AESGCM 加密 SHA384 负责验证的 Cipher,等等。

    现在网站证书里的私钥公钥的利用率其实是很小的。
    3dwelcome
        27
    3dwelcome  
       2018-06-08 09:43:43 +08:00
    @msg7086 你似乎对 AES_GCM 加密算法有什么误解。本身 GCM 和 CHACHA20_POLY1305 一样,都是属于 AEAD 同时处理数据验证和加密的算法。摘要算法默认都是为空的,和 SHA384 没一点关系。
    3dwelcome
        28
    3dwelcome  
       2018-06-08 10:02:30 +08:00
    GCM 的后缀 SHA384 只负责握手协议的摘要算法,只要握手成功后,所有的实际内容数据传输验证,SHA 都不会参与进去的。

    还有你说的 ECDSA,是需要网站签发 ECC 曲线证书的,有多少网站会折腾这个嘛,大部分还不是 RSA。

    诚然,TLS1.3 规定了不让用 RSA,是需要淘汰,但这不是没有普及的嘛。TLS1.3 改了太多协议上的东西,自己都咽到了,推广不开。虽然 RSA 慢,可现在有硬件加速卡,而且 TLS1.2 是有办法利用各种 resume ticket 黑科技,能把 RSA 的计算量大大减少。相比之下,TLS1.3 优势就没那么大了,也是很尴尬。
    manfred4527
        29
    manfred4527  
    OP
       2018-06-08 16:15:12 +08:00
    @3dwelcome
    突然想到一个问题
    我在访问一个 https 网站的时候
    网站服务器是先给我数字签名 还是先传网页内容

    我在网页里输入账号密码的时候 我要不要发一个数字签名给网站服务器
    如果我需要发数字签名给网站服务器 那是不是意味着我需要发一个公钥给网站服务器,然后用我自己的私钥加密摘要
    3dwelcome
        30
    3dwelcome  
       2018-06-08 16:28:17 +08:00
    @manfred4527 "如果我需要发数字签名给网站服务器 那是不是意味着我需要发一个公钥给网站服务器,然后用我自己的私钥加密摘要"

    完全正确,这在 SSL 里有专门的协定,叫做客户端证书验证。当服务器需要认证客户端的时候,会告诉客户端,让其发一个证书。比如 FIREFOX,会跳出对话框,让你手动选择一个证书。当你选择完成后,FIREFOX 就会用私钥来对证书签名,发到服务器。服务器通过这个证书,就知道你是谁谁谁了。

    当然,一般这种情况是对安全要求比较高的情况。比如 V2EX 录入用户名和密码,就没实现这种功能。通常来说,就是服务器给客户端数字签名,双方协定一个 KEY,建立加密通道后,再开始传输实际网页内容。
    manfred4527
        31
    manfred4527  
    OP
       2018-06-08 16:57:26 +08:00
    @3dwelcome
    那第一个问题
    我在访问一个 https 网站的时候
    网站服务器是先给我数字签名 还是先传网页内容
    3dwelcome
        32
    3dwelcome  
       2018-06-08 17:00:12 +08:00
    楼上回复了呀,通常来说,就是服务器先给客户端数字签名,建立加密通道后,再开始传输实际网页内容。

    你可以假设,任何通过 HTTPS 传输的数据,每一个字节,都是加密后的。
    manfred4527
        33
    manfred4527  
    OP
       2018-06-08 17:16:45 +08:00
    @3dwelcome
    有哪些网站是需要客户传送数字证书的呀?
    举个列子? 淘宝要吗?
    3dwelcome
        34
    3dwelcome  
       2018-06-08 17:25:50 +08:00
    @manfred4527 淘宝肯定不需要,因为加了客户端认证,就不是任何人都可以访问。

    一般只有公司 OA,或者对数据非常敏感的国外网站,才会加这种功能。
    msg7086
        35
    msg7086  
       2018-06-08 23:13:51 +08:00
    @3dwelcome SHA384 这个我不太熟悉,想当然了。
    至于 ECDSA,我也说了是「现代」。我自己网站 RSA+ECC 双证书已经很久了,ECC 证书优先,不支持的再回落,nginx 就能支持这种配置,LE 也可以轻松签发,我不觉得这哪里折腾了。

    @manfred4527 你说的这个叫做客户端证书,主要是认证用的,而不是加密。
    加密,现在主流的就是 DHE 和 ECDHE,双方什么东西都不用,凭空就可以建立起加密隧道防止窃听,然后通过验证服务器证书来防止中间人攻击。

    服务器生成:a = 123
    服务器说:A = 456
    客户端生成:b = 321
    客户端说:B = 765
    服务器和客户端现在知道密钥 s = 23432,以下所有消息都用 s 加密。
    服务器说:我证书是 X,公钥是 Y,用私钥签名后是 Z。
    客户端用 s 解密后,验证 X 可信,验证 X 包含 Y,验证 Y 和 Z 匹配。

    以上数字是乱填的,仅供演示之用。


    很久以前,加密是用 RSA 永久密钥生成的,后来因为向前安全性的原因,改用一次性密钥了,包括 ERSA (已失宠)和 DHE 家族(已上位),目的就是让加密与永久密钥独立开,保证有朝一日万一密钥泄露了,以前的通讯不会被同样破解。所以现在加密都是在证书交换之前就完成了,哪怕服务器没有 SSL 证书,原理上也是可以进行加密连接的。
    honeycomb
        36
    honeycomb  
       2018-06-09 16:24:16 +08:00 via Android
    @manfred4527 就这个话题来说,公钥是相同的,至于为什么公钥相同,还是建议你读一遍 TLS/HTTPS 的原理,这些已经有很好的文章阐述,在这里再说一遍反而没有那么清楚
    e8c47a0d
        37
    e8c47a0d  
       2018-08-09 10:28:35 +08:00
    首先公钥和私钥是仅出现在非对称加密。对称加密的密钥不存在公私之分。

    没错,公钥和私钥是一对的。目前没有也用不到一对多的情况。

    数字签名又是另外一回事,数字签名的目的尽在证明[我确实是谁谁谁]。

    我认为理解数字签名之前,先研究好 rsa 和 dh 等算法。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2154 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 00:43 · PVG 08:43 · LAX 16:43 · JFK 19:43
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.