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

即时通信 IM 端到端加密真的可以做到吗?

  •  1
     
  •   cxytz01 · 2022-09-06 11:59:10 +08:00 · 4408 次点击
    这是一个创建于 591 天前的主题,其中的信息可能已经有所发展或是发生改变。

    想象这么一个场景 client A 、B 都在 NAT 内部,它们需要通信,那么就需要经过 server 进行协商握手。不论后续是否成功进行 p2p ,亦或借助 server 进行转发,server 俨然就是一个中间人的角色,在协商阶段把 A 、B 的密钥全都替换成 server 的。

    只有两种种场景是可以端到端加密的:

    • 有个公告板,大家都把自己的公钥发布上去,这时候 server 是做不了手脚的。
    • 其中之一方在公网,且它的地址被另一方知道,双方直接通信,不借助 server 打洞。

    不知道描述得是否正确,请指正。

    41 条回复    2022-09-09 17:58:02 +08:00
    paramagnetic
        1
    paramagnetic  
       2022-09-06 12:10:56 +08:00
    你们必须有直接信息交换或者共同信任的中间人,除此之外没办法。大多数时候的“端到端加密”,是认为 server 就是一个可信任的中间人,然后你和 server 之间的可信任中间人是 CA 。如果这个信任链有问题,你唯一的选项是直接找到对方,然后当面交换公钥。
    这归根到底是个哲学问题,B 到底是谁,我又到底是谁?
    FengMubai
        2
    FengMubai  
       2022-09-06 12:12:12 +08:00
    有专门的密钥协商算法
    icegaze
        3
    icegaze  
       2022-09-06 12:16:51 +08:00 via Android
    在两个 NAT 内网的 pc 之间通讯,
    外部的 server 可以只作为寻址之用吧?
    通信可以直接发生在两个 pc 之间。

    然后,
    非全圆锥的 NAT ,需要 server 中转的,
    两个 pc 之间是不是可以再套一层加密,
    以防止 server 篡改内层原本的数据呢。
    agagega
        4
    agagega  
       2022-09-06 12:17:18 +08:00 via iPhone
    Signal 是可以当面相互确认公钥的(通过互扫二维码),Telegram 应该也可以
    icegaze
        5
    icegaze  
       2022-09-06 12:20:01 +08:00 via Android
    还有你说的公告板系统上大家登记自己的公钥,
    这个就是类似于现在的 CA 系统啊。

    现在的 CA 系统是逐层认证的,
    树状的公告板公钥登记模式而已。
    ysc3839
        6
    ysc3839  
       2022-09-06 12:22:45 +08:00
    中间人攻击的问题没什么好办法解决,参见 https 的证书体系。
    eason1874
        7
    eason1874  
       2022-09-06 12:26:58 +08:00
    需要第三方渠道来完成证书验证,比如可信 CA

    通过 server 无法掌控的第三方服务来交换公钥也行,比如你要防的是越南,那你就在不可能跟越南合作的 APP 上交换公钥,比如在 github 上交换
    tavimori
        8
    tavimori  
       2022-09-06 12:31:00 +08:00
    实际上现有的端到端加密其实是 key 到 key 的加密,只保证是发送端 key 的所有者到接收端 key 的所有者是保密的。至于怎样验证你要通信的对象的确是这个 key 的所有者,有两种普遍的模式:
    1. 基于权威机构的证书,也就是 X.509 。
    2. 基于面对面建立的信任网络,也就是 PGP 体系。
    CEBBCAT
        9
    CEBBCAT  
       2022-09-06 12:32:00 +08:00
    > 公告板
    ISP 也可以劫持你的流量给你看伪造的公告板
    > 一方是公网,用 IP 直接连接
    同上,ISP 也可以中间人攻击

    楼主提出的问题是经典的中间人攻击问题,除非倚靠第三方手段如 CA 、当面确认收到的密钥,否则无法规避

    总结:楼主 2015 年注册的,自学能力应该很强才对,这些问题 Google 搜索一下就好了。特别是有人专门讨论过 IM 端到端的设计的情况下。不能理解为什么还要提出这样入门级的问题。

    https://bdwms.site/e2ee/

    https://iangeli.com/2019/04/25/%E7%AB%AF%E5%AF%B9%E7%AB%AF%E5%8A%A0%E5%AF%86%E9%80%9A%E8%AE%AF%E5%8D%8F%E8%AE%AESignal-protocol-%E5%AD%A6%E4%B9%A0.html
    gkirito
        10
    gkirito  
       2022-09-06 12:40:59 +08:00 via iPhone
    想到 signal 好像就有这个功能,如果你不相信服务端发给你的 B 的公钥信息真假,可以双方发送自己的公钥二维码或者线下扫码确认验证
    7RTDKSAK
        11
    7RTDKSAK  
       2022-09-06 13:45:35 +08:00
    我赞同 7 楼所说

    1.如果是现实中认识地人之间加密通讯,可以考虑当面交换 KEY

    2.但是如果和虚拟世界中地网友之间通讯,而且还需要加密,这样地情景其实不多,这种情况下通讯双方只能通过第三方来建立第一次联系,所以必然存在"选择哪一个第三方"/"该第三方是否可信"/"如果该第三方不可信又如何"等等一系列问题
    zhengxiaowai
        12
    zhengxiaowai  
       2022-09-06 13:55:51 +08:00
    了解一下 signal protocol
    duke807
        13
    duke807  
       2022-09-06 14:10:07 +08:00 via Android
    我用 matrix 很多年,最开始用了一下 端到端 加密,后来再也不想用,因为太麻烦,特别是群组加密

    就不能搞一个对称加密吗?群内成员共享一个密码

    想进一步还可以:群组加人的时候,群主负责和所有成员交换 RSA 公匙(成员之间不用),群主把 AES key 用每个组员的 RSA 公匙加密,放置在服务器上(同时加上群主的 RSA 签名),每个组员从服务器获取最新的 AES key 用来加解密群内聊天内容。这样,可以定期修改 AES key 增强安全性。还可以指派几个管理员享有群主同等权利。

    无论是直接交换 AES 密码,还是交换 RSA 公匙,都可以使用第三方的阅后即焚服务。

    目前,我用的是自己写的通用 IM 开源加密工具,首次交换密码我喜欢用阅后即焚,确保对方收到密码,才使用此密码加密:
    https://www.v2ex.com/t/832302
    见连接提到的更多技巧
    Roanapur
        14
    Roanapur  
       2022-09-06 14:17:52 +08:00
    可以做到。

    你的担忧不是端对端加密的漏洞,而是中间人攻击的问题。

    一切的安全措施,都有一些前提吧。
    yisiliu
        15
    yisiliu  
       2022-09-06 14:34:43 +08:00
    不考虑群组聊天的话非常简单,但是如你所说,其实最麻烦的还是这个握手的时候如何验证对方的 authenticity ,于是这里其实就变成了一个身份问题,这也是为什么你用 signal 的时候会推荐你线下 verify 对方的身份(公钥),这样之后在握手的时候,其实做的就是互相签名,来确保不被中间人替换密钥了。当然了,在真的做通讯的时候也有一些需要注意的问题,比如说如何保证 forward secrecy ,这里就要提到一个 ephemeral key 的概念,ie 每一条消息都由一个一次性的密钥进行加密,真实性靠上一个密钥或者不变的那个 public key 对应的私钥签名来提供保障。具体的加密方法可以参考: https://en.wikipedia.org/wiki/Integrated_Encryption_Scheme

    > 有个公告板,大家都把自己的公钥发布上去,这时候 server 是做不了手脚的。
    > 其中之一方在公网,且它的地址被另一方知道,双方直接通信,不借助 server 打洞。

    这个可以看看 pgp 的 key server 或者 keybase ,server 是否能动手脚不在于说是不是一个公共的公告板,而在于说每个公钥都是签过名的。

    当然了,也可以看看我们在做的 https://docs.next.id
    sy20030260
        16
    sy20030260  
       2022-09-06 14:38:35 +08:00
    虽然但是,这里有个概念问题。

    端到端加密和可信中间人是两个不同的问题。密钥不泄漏 or 不被伪造是端到端加密的“预设条件”,而非其“目标问题”呀。在满足密钥不泄露的前提下,可以做到除了发送端和接收端之外的其他节点无法获取明文信息,就是完备的端到端加密了

    举个最极端的例子:即使是使用 Signal 通过当面交换公钥,但是用户在实际使用中使用了不受信任的物理设备,导致密钥直接在物理层面泄露了,这也会导致信息泄露发生。但这并不能说明 Signal 提供的端到端加密是假的或不完备的...
    ren2881971
        17
    ren2881971  
       2022-09-06 14:40:27 +08:00
    可以用那个协同密钥。 客户端和服务端组合一起才能解密。
    rekulas
        18
    rekulas  
       2022-09-06 14:51:01 +08:00
    “亦或借助 server 进行转发,server 俨然就是一个中间人的角色,在协商阶段把 A 、B 的密钥全都替换成 server 的。”

    这个中间人的定义就不太准确,参考中间人攻击方式,server 要换密钥,那 client 就要信赖 server 才行,既然你都信任 server 了,那就相当于自己 hack 自己了。只要你只认可合法 client 的证书,server 没法攻击
    dingwen07
        19
    dingwen07  
       2022-09-06 14:56:15 +08:00 via iPhone
    @paramagnetic #1 不哲学。如果这个人是你能见面的,那线下验证一下密钥很简单

    现在主流聊天软件的端对端问题是,客户端不开源,你不知道它显示给你线下确认的 pk 的是不是真的
    nomagick
        20
    nomagick  
       2022-09-06 15:00:05 +08:00
    什么鬼都在瞎说八道一些什么,明明 2 楼就是正解
    都没没听过 Diffie-Hellman 么, 在双方不直接发送密钥的前提下完成密钥交换。

    你再仔细想想除了 server, 这条网络线路上所有交换机路由器不全部经手你的数据么,按你这么说加密根本没法做了
    krixaar
        21
    krixaar  
       2022-09-06 15:04:29 +08:00
    了解一下 OMEMO ?
    mokiki
        22
    mokiki  
       2022-09-06 19:46:27 +08:00
    内网的话可以扫描整个内网 ip 端口来连接,不需要电脑这样的 server 。此时交换机就是中间人,因你没法保证这个交换机不是含有两个网口的电脑。这种情况只有一楼的方法能保证互相信任。

    至于 DH 什么的,也需要用安全的通道事先知道对方的公钥,或通过信任第三方获取对方公钥,典型应用就是 CA 证书体系的浏览器。我就不信有人能把电脑和浏览器的证书都删掉还能用 DH 交换出安全密钥。
    rekulas
        23
    rekulas  
       2022-09-06 23:50:34 +08:00
    @nomagick 密钥交换只是其中一个逻辑啊,光有交换算法也没法通信,都说远了最简单的 https 通信就是一个非常安全的端端通信,在不自黑的情况下目前没办法破解
    urnoob
        24
    urnoob  
       2022-09-07 00:14:56 +08:00 via Android
    可以,思科的 webex 应该是端到端加密的
    iX8NEGGn
        25
    iX8NEGGn  
       2022-09-07 00:29:15 +08:00 via iPhone
    @nomagick 你不会天真认为 DH 算法能防止中间人攻击吧,中间人可以两端都骗,算出两端的密钥,最终解决方案就是和 TLS 一样,引入 CA 才能解决。
    nomagick
        26
    nomagick  
       2022-09-07 04:07:23 +08:00 via Android
    @iX8NEGGn
    @mokiki
    大哥 DH 自己就这么不堪么,你们是都不用 ssh 登服务器么,ssh 就没 CA ,照这么说没法用了
    等下回连新机器人问你相信不相信对方的 key 的时候,回答否然后给机房打电话确认一下?
    akira
        27
    akira  
       2022-09-07 06:08:19 +08:00
    信任都是有基础假设条件的啊。
    在 server 不可信的前提下,AB 之间连身份都无法信任了。
    rekulas
        28
    rekulas  
       2022-09-07 09:11:00 +08:00
    @nomagick 那你仔细想一想,要求你确认的目的是什么?就是为了让你自己负责对方是否可信啊,那么问题来了

    如果你没有第三方认证机构,你确认的时候怎么知道对方是否可信呢?如果是假冒的你也无法分别
    如果你说你本地存储了一份信任服务器名单,那又有个新问题,信任名单是从哪里来的呢?如果你通过网络传输,那又陷入了中间人攻击的怪圈。如果你是直接提前协商写死的,那么既然都可以提前协商了还用 dh 干什么,直接写死每个服务器通信对应的加密 key 不就完了?所以说光是 dh 是无法解决端端通信的
    dbolo123
        29
    dbolo123  
       2022-09-07 09:27:55 +08:00 via Android
    @nomagick ssh 第一次连接是会被攻击的,所以第一次连接会问你是否信任
    dbolo123
        30
    dbolo123  
       2022-09-07 09:32:33 +08:00 via Android
    @dbolo123 安全一点的做法可能是,都选否,然后通过其他方式获取对方公钥,配在自己服务器上,再去连
    iX8NEGGn
        31
    iX8NEGGn  
       2022-09-07 09:35:19 +08:00
    @nomagick SSH 推荐的安全登录方式是证书登录,怎么就没 CA 了,密码模式确实没 CA ,但它就是这么的不堪,随时被中间人工具,你能用不代表它安全,只是没人攻击你罢了。
    nomagick
        32
    nomagick  
       2022-09-07 10:31:17 +08:00
    @iX8NEGGn 你把密钥和证书搞混了,ssh 出现得早,没有 CA

    @rekulas 我寻思 CA 就是你那个本地信任服务器名单啊,而且这里面核心就是事先已知,而不是你说的第三方,
    CA 证书的后续分发也是通过网络

    @dbolo123 我不信 ssh 问你的时候你答了否

    而且我发现本帖对 CA 的认知也不够深,CA 和证书不是只管密钥的,它是将密钥和其他信息进行关联,否则毫无意义,而这个关联的过程是需要 CA 自己单独去进行的,比如一般网站的证书是将密钥和域名关联起来,CA 需要单独验证你是不是持有这个域名。

    那么在本帖的场景下如果使用 PKI 那 CA 需要签署什么呢? 基本上是 UserID 或者 Email 之类的东西吧,那 CA 又从何验证密钥的持有者同时是 UserID 或者 Email 的所有者呢?

    明白了吧,根本不现实。

    这个帖子讨论的是端到端通信,而不是端到端连接,好比完成密钥交换之后使用 Email 收发密文,所以不要把思维局限在 TLS 上。

    所以说关键点就是密钥交换,场景和 ssh 非常相似
    rekulas
        33
    rekulas  
       2022-09-07 11:13:21 +08:00
    @nomagick ca 并不是信任服务器名单,它只是一个授信机构,也就是初始化的时候可能没有任何证书,唯一的共识就是-所有人都信任 ca ,然后进入通信环节,ca 通过各种认证向客户端办法证书,大家都信任,通信才能继续。

    ca+密钥交换,可以实现在不可信网络中的可信通信,这正好是 op 的需求,也是 https 的基础原理
    回到你的疑问-ssh 就没 CA ,照这么说没法用了
    可以用,但是你的通信时在不可信网络中的不可信通信,通信中的任何一个中间设备都可以对你发起攻击

    要说主要的漏洞,可能就是 ca 认证环节了,如果认证不够严格可能会被伪造证书,但鉴于其超低概率和高难度基本可以认为是足够安全的,毕竟我们的互联网就运行在这套理论上而且稳定几十年了
    rekulas
        34
    rekulas  
       2022-09-07 11:25:06 +08:00
    @rekulas 补充一句,其实普通的 ssh 证书登录也是用了 ca 的,只不过 ca 是自己并不被系统信任,所以开始的时候会询问你是否信任。

    完全不依赖 ca 呢?也是可以通信的,但是如上仍然是不可信通信
    iX8NEGGn
        35
    iX8NEGGn  
       2022-09-07 11:25:41 +08:00
    @nomagick SSH 三种登录模式:密码,公钥密钥,证书,我没有搞混,是你不了解技术进步了。
    BloodBlade
        36
    BloodBlade  
       2022-09-07 13:15:28 +08:00
    ssh 直接回答 yes 是基于对服务器提供商的信任吧,如果提供商在第一次连接就进行中间人攻击,这时候直接回答 yes 不就中招了?
    yhvictor
        37
    yhvictor  
       2022-09-07 13:46:36 +08:00 via iPhone
    关于 ssh 说几句。
    使用公钥通信,只要公钥传到了远端服务器上。
    即使有中间人应答,中间人也无法解密通信内容。
    也就是第一次回答 yes 也无所谓。

    @BloodBlade
    yhvictor
        38
    yhvictor  
       2022-09-07 14:42:20 +08:00 via iPhone
    如果区块链可信的话是可行的。
    只要登登记 id 和公钥就行。
    比如说张三李四登记了。
    那么张三一定能发出一条只有李四才能解密的信息。
    不过:
    李四能不能收到要看网络上让不让传(某墙),或者信息也上链。
    rekulas
        39
    rekulas  
       2022-09-07 15:03:36 +08:00
    @yhvictor 确实,你说的对,如果提前拷贝了 ssh 公钥,这种情况无法进行中间攻击。但是这又回到了最早的情形-既然都可以通过某种方式将公钥可信的传递到服务器,那么有没有密钥交换都无所谓,端端通信跟 dh 没关系了。这个我是针对 nomagick 的回复说的。

    我也是做区块开发的,至于区块链我跟你看法也一样,区块链本身协议无法提供可信保障,现有的区块链其实都存在这个漏洞的,只不过区块链中间人攻击几乎没有什么收益,而且节点多攻击成本也高-有那能力还不如 51 攻击。
    公钥加密-解决不可信网络的可信通信(如 https)
    私钥加密-解决不可信网络的身份认证(如区块链)
    BloodBlade
        40
    BloodBlade  
       2022-09-07 17:07:26 +08:00
    @yhvictor 我的意思是,公钥一般是在购买服务器前先传到云服务提供商,购买服务器后再由提供商写入到服务器上,这个过程中公钥会在提供商中经过一次。如果先开服后上传公钥的话,也要通过密码连接或者提供商的后台来传上去,同样也存在被提供商利用的可能性。
    daBig
        41
    daBig  
       2022-09-09 17:58:02 +08:00
    搜一下 E2EE ,DH 秘钥交换算法就知道了
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   1134 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 23:42 · PVG 07:42 · LAX 16:42 · JFK 19:42
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.