V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
amiwrong123
V2EX  ›  程序员

对于“公钥加密,私钥解密”有在 ssh 的 authorized_keys 这种常见的应用场景,那么“私钥签名,公钥验证”有什么常见的应用场景?

  •  1
     
  •   amiwrong123 · 56 天前 · 5068 次点击
    这是一个创建于 56 天前的主题,其中的信息可能已经有所发展或是发生改变。
    个人目的只是想从 应用使用的角度来理解,非对称加密、公钥私钥这些概念。

    对于 ssh 的`authorized_keys`的应用使用过程为:
    ● 服务器检查 `authorized_keys` 文件,找到与客户端提供的公钥匹配的条目。
    ● 服务器生成一个随机数,并使用公钥对其进行加密,然后将加密后的消息发送给客户端。
    ● 客户端使用私钥解密该消息,并将解密后的随机数返回给服务器。
    ● 服务器验证返回的随机数是否正确。如果正确,服务器接受客户端的连接请求。
    从这个过程,理解了"正因为客户端使用了私钥来解密,所以才能证明客户端的身份。",而且反过来,“私钥加密,公钥解密”是无法证明身份的。
    自己也去 ssh 连接了多个服务器,查看了`authorized_keys`的内容。也看了客户端自己`~/.ssh/id_rsa.pub`。


    那对于“私钥签名,公钥验证”,有什么应用场景是平时接触得到的?
    - 而且最好有实物可以查看,帮助理解。
    - 而且要是能有一个和我上面差不多的简单分析,就更好了。
    60 条回复    2024-09-23 16:30:17 +08:00
    xmumiffy
        1
    xmumiffy  
       56 天前 via Android
    https 证书就是
    imdong
        2
    imdong  
       56 天前 via iPhone
    你怎么证明这句话是你说的?
    kera0a
        3
    kera0a  
       56 天前 via iPhone
    私钥加密,公钥解密 恰恰就能证明身份啊,在说什么啊兄弟
    R18
        4
    R18  
       56 天前   ❤️ 18
    公钥加密->私钥解密 别人发给你信息,确保这个信息只有你能解密
    私钥签名->公钥验证 你发一条信息出去,任何知道你公钥的人都能验证这条信息是来自于你
    kaichen
        5
    kaichen  
       56 天前
    区块链,证明我持有这把公钥对应的私钥

    1. 用私钥签名一段数据哈希(如转账)
    2. 网络节点还原哈希对应的公钥(椭圆曲线)验证公钥所有者,以及检查公钥所有者记账的金额余额

    区块链上的账目实际上是记录在公钥上,即某个公钥持有对应资产数量
    maichael
        6
    maichael  
       56 天前
    几乎所有的区块链/数字货币
    NessajCN
        7
    NessajCN  
       56 天前
    这个顾名思义就知道了啊
    签名的作用就是让别人知道某段信息是只有我能发出的
    譬如我是某机构,我要发一篇公告,我把公钥公开出去,再用私钥加密这篇公告的内容发出去,
    别人用公钥解密成功的文本就说明是本机构发出的,任何其他人都伪造不了
    应用场景么像是软件分发时候在 manifesto 里加上私钥信息表明分发源可靠之类
    公钥加密的作用是对密文本身保密,私钥签名对密文本身是不保密的,仅仅是证明密文发出者的身份可靠
    crackidz
        8
    crackidz  
       56 天前
    GPG 你提到两部分包含两部分:

    公钥持有者使用接受者公钥加密,只有指定的接受者才能解密查看邮件内容。
    同时,发送者使用私钥进行签名,接受者使用发送者的公钥验证邮件是由真实的发送者发送。

    这就是双向验证。
    jinliming2
        9
    jinliming2  
       56 天前 via iPhone
    软件的数字签名,开发者用私钥签名,用户使用公钥验证软件来源且未被篡改。
    amiwrong123
        10
    amiwrong123  
    OP
       56 天前
    @NessajCN #7
    等等。
    首先,“私钥签名->公钥验证”,你发一条信息出去,任何知道你公钥的人都能验证这条信息是来自于你。

    然后,你说的,“私钥加密公告->别人用公钥解密”,也能达到这个目的“你发一条信息出去,任何知道你公钥的人都能验证这条信息是来自于你”呗。
    - 因为公钥是公开的,所以其实谁都可以解密。
    - 但至少可以证明 信息发送者的身份。

    神奇,这两种方式都可以达到这目的。😮
    NessajCN
        11
    NessajCN  
       56 天前
    @amiwrong123 ?? 你这个 首先 , 然后 说得不是同一个操作吗
    啥叫两种方式
    amiwrong123
        12
    amiwrong123  
    OP
       56 天前
    @NessajCN #7
    而且我开始以为“私钥加密,公钥解密”这种没有用呢,差点被自己误导了。

    也就是说,
    “公钥加密,私钥解密”
    “私钥加密,公钥解密”——软件的数字签名
    “私钥签名,公钥验证”——httts 证书
    都有应用场景。
    只是最后两种应用场景的目的,都是一样的目的。
    LaTero
        13
    LaTero  
       56 天前
    @amiwrong123
    “私钥加密,公钥解密”——软件的数字签名
    “私钥签名,公钥验证”——httts 证书
    就是同一个东西
    amiwrong123
        14
    amiwrong123  
    OP
       56 天前
    @NessajCN #11
    啊?我理解错了吗。。
    加密是:原 content -> 加密的 content
    签名是:原 content -> 原 content+一个签名值
    这不是两种操作吗
    NessajCN
        15
    NessajCN  
       56 天前   ❤️ 4
    @amiwrong123
    哦我知道了,你是不是一直误解了“签名”的意思?
    以为是把分发者的个人信息用私钥加密一下叫签名?
    不是的,这里的签名其实是一个操作,用私钥把真实内容加密,因为加密后的密文其实不保密,所以就把这个加密操作改叫签名
    amiwrong123
        16
    amiwrong123  
    OP
       56 天前
    @NessajCN #15
    我好像懂 你意思了,我之前一直误解了。。

    假设有一个文件 data.txt ,我们分别对其进行加密和签名:
    加密:
    发送方使用接收方的公钥对 data.txt 进行加密,生成 data_encrypted.txt 。
    接收方使用自己的私钥对 data_encrypted.txt 进行解密,恢复 data.txt 。
    签名:
    发送方计算 data.txt 的哈希值,然后使用自己的私钥对哈希值进行签名,生成 signature.txt 。
    接收方使用发送方的公钥验证 signature.txt ,确保 data.txt 未被篡改且来自预期的发送方。

    上面这段是大模型的回答,所以“用自己的私钥对哈希值进行签名”就是指,用私钥加密呗。
    churchmice
        17
    churchmice  
       56 天前 via Android
    没有私钥加密,公钥解密这种说法
    签名操作不是个加密,对于 rsa 这两操作看着像但是不能混成一谈
    NessajCN
        18
    NessajCN  
       56 天前   ❤️ 1
    @amiwrong123
    还是有误解,私钥签名==私钥加密
    所以你说的“用自己的私钥对哈希值进行签名” 等价的说法并非“对 dtata.txt 签名” 而是“对 data.txt 的哈希值进行签名”
    对 data.txt 签名指的是用私钥对 data.txt 全文加密
    amiwrong123
        19
    amiwrong123  
    OP
       56 天前
    @NessajCN #18
    OK ,感谢回答,理解了。这中间会有一步算哈希的步骤。

    签名:
    发送方计算 data.txt 的哈希值,然后使用自己的私钥对哈希值进行签名,生成 signature.txt 。
    接收方使用发送方的公钥验证 signature.txt ,确保 data.txt 未被篡改且来自预期的发送方。

    -------------------------

    问一个比较笨的问题,把上面的过程改成:
    用私钥对 data.txt 全文加密。这种方式不常用吗?或者本身这种有什么弊端?

    主流的,应该还是,发送方先算出哈希值,再对哈希值进行加密吧。
    NessajCN
        20
    NessajCN  
       56 天前
    @amiwrong123 这两种方法本质没区别啊,你思考一下就知道了
    cxh116
        21
    cxh116  
       56 天前 via Android
    linux 的包就是私钥签名,公钥验证,防止镜像站等中间人篡改,添加恶意代码。
    leonshaw
        22
    leonshaw  
       56 天前 via Android   ❤️ 1
    非对称加密基本上不会直接对数据操作。消息加密是用对方公钥加密一个对称密钥,用对称密钥加密数据。签名是用自己的私钥加密消息内容的 digest 。 会话场景是用于密钥交换阶段。
    seers
        23
    seers  
       56 天前 via Android
    你做过逆向就知道,现在很多 app 就是带了一个 rsa 私钥,然后给 packet 签名发服务器,服务器用公钥验证,这个私钥会用各种方法隐藏起来,防止攻击者找到
    Exxfire
        24
    Exxfire  
       56 天前
    数字签名的主要作用是保护信息的完整性和防止抵赖。
    数字签名的过程:A ----> B 发送一条数据,数据和签名是分开发的。
    1. A 先使用摘要算法算出摘要;
    2. A 使用自己的私钥对摘要进行加密;
    3. A 发送数据给 B ;
    4. A 发送签名给 B ;
    5. B 收到签名后先使用 A 的公钥进行解密;(体现了防止抵赖的特性)
    6. B 收到数据后进行摘要计算,和签名解密出来的摘要进行对比;(验证数据的完整性)

    需要注意的是,出于保密性需求,数据发送前也可以使用某种算法进行加密,密钥及算法协商涉及其它过程。
    这是书本上学习理解到的知识,没有验证过。
    Exxfire
        25
    Exxfire  
       56 天前
    非对称加密算法通常不用于数据处理的原因应该是出于性能方面的原因考虑,非对称算法复杂度高,效率低;(相对于对称加密算法而言)
    iOCZS
        26
    iOCZS  
       56 天前
    取决于解密的数据给谁看,给别人看就公钥解密,给自己看就私钥解密
    LemonNoCry
        27
    LemonNoCry  
       56 天前
    @R18 通俗易懂
    LLaMA2
        28
    LLaMA2  
       56 天前   ❤️ 4
    @amiwrong123

    请务必牢记规则

    公加私解
    私签公验

    很多系统中总会存在部分数据有客户端提供,此时客户端总是不可信的,于是我们将公共密钥一道提供给他,
    他公加密,我私解密,这样保证数据传递过程中的安全

    我私签名,签名内容由客户端自行决定,我签名后传回给客户端,客户端使用公验证签名和他提供的内容是否正确,使得客户端确认我(服务端)不是个冒牌的

    总之,如果一个系统中存在 RSA 用于抵御伪造攻击
    那么谁持有私钥就必然要证明自己的权威性,此时私签(对什么内容签名由客户端说了算),客户端公验,从而使得客户端确信这个持有私钥的人就是他要找的人

    谁持有公钥的人在任何时候传递数据的都公加,公加后的结果连客户端自己都无法解密(实际上客户端不需要解密,因为数据都是自己提供的,他根本不需要解密,只是为了在传递过程中不让其他人解密而已),只有持有私钥的人才能顺利解密
    Xheldon
        29
    Xheldon  
       56 天前
    典型的当然是产品激活验证码,我把公钥内置到产品里面用来验证购买的私钥加密的授权码是否可用。
    amiwrong123
        30
    amiwrong123  
    OP
       56 天前 via Android
    @churchmice
    为什么没有这种说法啊?签名操作的本质不就是一个加密操作吗
    minottomie4383
        31
    minottomie4383  
       56 天前
    很多,公私钥都是非对称加密用。
    私钥签名,公钥验签。公钥加密,私钥解密。是因为通常公钥是公开的,私钥是个人的,而各个语言和工具也是按照这实现和提供调用的
    私钥签名,公钥验证,例如三方 API 也可以用,像接支付宝接口,银行支付接口,你会看到他们也有用公私钥方案。平台会提供你他们的公钥用于验签他们的响应包,你也要提供你的公钥给平台用于验签你的请求。为的就是互相证明双方身份。
    当你开发开放接口给别人调用,且只能给指定的调用方调用,不让别人随便调用,也可以上签名这一套,安全级别较高的就用公私钥。
    LLaMA2
        32
    LLaMA2  
       56 天前
    @amiwrong123 #30

    姑且就当你私加公解了吧,前面我说了,这一套最终的目的是为了抵御伪造。
    好了,公钥是公开的,所以叫公钥,也就是路人也能合法地取得公钥,你现在服务器使用私钥加密,你本期待着客户端顺利解密,然后顺顺利利地干活,不成想,半路有个蟊贼把数据原样拓印了一份,他也可以顺利使用公钥解密,客户端也不知道数据半路被劫道了。还自信地说,我这加密没人能破,

    是的,蟊贼并没有破,但他也知道了服务器给你的数据的真实内容是什么,这是泄密啦!!!
    为什么呢,因为蟊贼并没有伪造任何数据,他只是拓印了一份,本来你严格遵守公加私解,私签公验是不会出现他能解密的情况发生,结果你错误地使用,导致他能解密服务器发给你的数据,这属于使用不当。

    总而言之,你需要借助这个 RSA 传递一些不可以让第三方知道的内容。你私加公解用起来完全没问题,可第三方知道了你们之间对话内容的一半(服务器告诉你的内容),因为你没有正确地使用

    公加私解
    私签公验

    牢记牢记
    vishun
        33
    vishun  
       56 天前
    没有对接过支付宝支付、微信支付这些吗?这里面就有。
    wnpllrzodiac
        34
    wnpllrzodiac  
       56 天前
    图解密码技术
    https://bkimg.cdn.bcebos.com/pic/80cb39dbb6fd526699ac8e84a718972bd507369e
    可以看看这本书。浅显易懂。

    非对称加密,主要解决的是密钥传输过程中被窃取的问题。
    就是鸡和蛋的问题。怎么保证密钥的安全呢?密钥再加密?可是这个加密密钥的密钥怎么保证安全呢?
    天才想出来一个法子,可以在明码传输密钥的情况下,也不会被破解。

    核心就是一个大数怎么取模。找到另一个数。正常情况下,这个计算非常吃时间,就可以认为你就算有了公钥,也不可能计算出保密的私钥。
    R18
        36
    R18  
       56 天前   ❤️ 1
    @amiwrong123
    加密、签名 的本质区别就是你的密文是由公钥生成的还是私钥生成的。公钥是你公开出去的,私钥加密出来的密文人人都可以解密,所以就其实就失去了“加密”的性质,但是它可以用来验证这段文本确实是私钥持有者产生的。

    公钥、私钥是人为定义的密钥对的称呼,从数学上看 加密、签名 用的算法都是一样的。但是从工程实现上、生成的密钥对中私钥中还保存了生成密钥对所需的信息,通过私钥中所包含的信息,可以生成公钥。所以私钥是不可以公开出去的。

    日常应用中,楼上的网友也讲的很清楚了,因为性能问题。加密传输其实加密的是对称加密算法所需的密钥。签名实际签名的是消息摘要。
    kxg3030
        37
    kxg3030  
       56 天前
    第一个已经回答了 https 就是典型的场景》...
    CodeAllen
        38
    CodeAllen  
       56 天前
    并不是所有非对称加密算法都支持加解密数据,非对称加密算法的基本要求是签名-验签,确认签名数据的准确性,确定身份,加解密并不是核心要求,加解密数据那是对称加密算法的活儿,而且还有一点,非对称加密算法对同样的数据进行多次签名,得到的签名数据不保证完全一样,可能存在随机值参数,和具体算法实现有关系,只要能验证通过就行。
    expy
        39
    expy  
       56 天前
    https://archlinux.org/iso/2024.09.01/archlinux-2024.09.01-x86_64.iso.sig

    系统镜像是常见场景,不过一般省事只验 sha 校验和。
    james122333
        40
    james122333  
       56 天前 via Android
    其中一个答案是包管理器 用来验証下载下来的包是否正确 目前最常用场景
    mark2025
        41
    mark2025  
       56 天前
    ssh 也可能双向认证的: 即认证服务端,也认证客户端
    neilp
        42
    neilp  
       56 天前
    现在的公钥私钥, 主要都是来签名的, 几乎不在直接加密了.
    ssh 或者 ssl/tls 中, 都是用 dh/ecdh 来动态协商产生对称加密密钥. 最后,用公钥私钥来签名就好了. 因为对称的密钥不需要通过网络传输, 所以不存在加密的问题.
    amiwrong123
        43
    amiwrong123  
    OP
       56 天前
    @expy #39
    那如果是不省事的做法呢,还会做啥呀
    amiwrong123
        44
    amiwrong123  
    OP
       56 天前
    @mark2025 #41
    authorized_keys 我知道是服务器用来验证客户端的身份的。
    你说的“认证服务端”,是指那个客户端保存的 known_hosts 文件吗?

    但我看了 known_hosts 的用法:
    A 通过 ssh 首次连接到 B ,B 会将公钥 1 传递给 A ,A 将公钥 1 存入 known_hosts 文件中,以后 A 再连接 B 时,B 依然会传递给 A 一个公钥 2 ,OpenSSH 会核对公钥,通过对比公钥 1 与公钥 2 是否相同来进行简单的验证,如果公钥不同,OpenSSH 会发出警告, 避免你受到 DNS Hijack 之类的攻击。

    ---------

    只是一个很简单的对比 公钥 1 和公钥 2 啊
    raw0xff
        45
    raw0xff  
       56 天前
    我记得有个开源项目 nostr 貌似可以做个例子。
    大概是个去中心化的 twitter 微博,用户信息和数据存在第三方建立的节点上(relay),用户可选择在多个不同的 relay 上存储自己和订阅别人,用户 ID 就是公钥,用户明文发推,但私信用接收者公钥加密。relay 只需要无脑收发存储,不需要对用户做任何身份验证。
    wOuv7i4e7XxsSOR1
        46
    wOuv7i4e7XxsSOR1  
       56 天前
    你的问题在于书读的不多但想的太多
    amiwrong123
        47
    amiwrong123  
    OP
       56 天前
    @Xheldon #29
    哈哈,没想到有你这个应用场景。
    geelaw
        48
    geelaw  
       56 天前 via iPhone   ❤️ 1
    请看 /t/519617 里面我的回复。

    @kera0a #3 @NessajCN #7 #11 #15 #18 #20 @amiwrong123 #10 #19 #30 @LaTero #13
    @iOCZS #26 @R18 #36

    “用私钥加密,用公钥解密”在任何一本密码学教材上都不会出现。此外,私钥加密蕴涵着数字签名(这是一个公钥对象),但目前不知道数字签名蕴涵着公钥加密。

    另请参阅 https://www.zhihu.com/question/432504839/answer/1681747812 答案和评论区。
    expy
        49
    expy  
       55 天前
    @amiwrong123 就你标题里的验签名啊,https://archlinux.org/download/ Download verification 有详细说明。
    neptuno
        50
    neptuno  
       55 天前
    也可以用来发邮件
    jiefengwang
        51
    jiefengwang  
       55 天前
    GitHub 或者其他的代码托管平台,对于 commit 的提交进行签名,应该属于是这个场景吧
    moioooo
        52
    moioooo  
       55 天前 via iPhone
    公钥加密的东西,只有私钥可以解密,
    私钥加密的东西,也只有公钥可以解密。
    由此引申的个种用法,利用的是以上两种机制。
    最好理解的,公钥是公开的,私钥是藏起来自己用。
    我用私钥加密了个文件,所有人可以用公钥解密。这叫数字签名,证明是我发的。
    你用公钥加密一个文件给我,只有我可以用私钥解密,这个用于数据传输。
    xiaokongwu
        53
    xiaokongwu  
       55 天前
    PDF 数字签名,就是私钥签公钥验
    mark2025
        54
    mark2025  
       55 天前
    @moioooo 加密和签名还是有区别的,前者是加密出密文,必须解密还原才知道明文;后者对原文(可以是明文也可以是密文)散列值进行签名,用于验证原文是否有变化。
    mark2025
        55
    mark2025  
       55 天前
    @amiwrong123 哈哈,其实前面说的双向验证值得是 SSH 登录时 SSL/TLS 层面的操作,不是你标题说的 authorized_keys 相关的验证~~
    mike1936
        56
    mike1936  
       55 天前
    说一个场景:JWT ,用户(浏览器之类的)向认证服务器提供登录信息,认证服务器验证后把用户对应的资源访问权限信息( Payload )用 [认证服务器的私钥签名] ,之后把权限信息和签名( JWT )返回给用户,用户拿到 JWT 之后带着个 JWT 去请求,资源服务器用 [认证服务器的公钥验证] JWT 里的没有被篡改,根据 JWT 里面的权限信息给用户返回对应的资源数据
    rajab
        57
    rajab  
       55 天前
    各个 Linux 发行版的源仓库中的各种包,都是用作者的私钥签名,然后系统内置了他们的公钥来验证包是否被篡改或是被 认证的,不知道我的理解对不对
    proxytoworld
        58
    proxytoworld  
       55 天前
    @amiwrong123 #10 在没有约定 数据格式的情况下,没办法使用公钥证明身份

    多的我也懒得说了
    proxytoworld
        59
    proxytoworld  
       55 天前
    @proxytoworld 使用密钥加密,只有使用密钥签名才可以验证身份
    hanyuwei70
        60
    hanyuwei70  
       54 天前
    SSH 是典型的私钥签名,公钥验证……
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   999 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 20:35 · PVG 04:35 · LAX 12:35 · JFK 15:35
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.