想象这么一个场景 client A 、B 都在 NAT 内部,它们需要通信,那么就需要经过 server 进行协商握手。不论后续是否成功进行 p2p ,亦或借助 server 进行转发,server 俨然就是一个中间人的角色,在协商阶段把 A 、B 的密钥全都替换成 server 的。
只有两种种场景是可以端到端加密的:
不知道描述得是否正确,请指正。
1
paramagnetic 2022-09-06 12:10:56 +08:00
你们必须有直接信息交换或者共同信任的中间人,除此之外没办法。大多数时候的“端到端加密”,是认为 server 就是一个可信任的中间人,然后你和 server 之间的可信任中间人是 CA 。如果这个信任链有问题,你唯一的选项是直接找到对方,然后当面交换公钥。
这归根到底是个哲学问题,B 到底是谁,我又到底是谁? |
2
FengMubai 2022-09-06 12:12:12 +08:00
有专门的密钥协商算法
|
3
icegaze 2022-09-06 12:16:51 +08:00 via Android
在两个 NAT 内网的 pc 之间通讯,
外部的 server 可以只作为寻址之用吧? 通信可以直接发生在两个 pc 之间。 然后, 非全圆锥的 NAT ,需要 server 中转的, 两个 pc 之间是不是可以再套一层加密, 以防止 server 篡改内层原本的数据呢。 |
4
agagega 2022-09-06 12:17:18 +08:00 via iPhone
Signal 是可以当面相互确认公钥的(通过互扫二维码),Telegram 应该也可以
|
5
icegaze 2022-09-06 12:20:01 +08:00 via Android
还有你说的公告板系统上大家登记自己的公钥,
这个就是类似于现在的 CA 系统啊。 现在的 CA 系统是逐层认证的, 树状的公告板公钥登记模式而已。 |
6
ysc3839 2022-09-06 12:22:45 +08:00
中间人攻击的问题没什么好办法解决,参见 https 的证书体系。
|
7
eason1874 2022-09-06 12:26:58 +08:00
需要第三方渠道来完成证书验证,比如可信 CA
通过 server 无法掌控的第三方服务来交换公钥也行,比如你要防的是越南,那你就在不可能跟越南合作的 APP 上交换公钥,比如在 github 上交换 |
8
tavimori 2022-09-06 12:31:00 +08:00
实际上现有的端到端加密其实是 key 到 key 的加密,只保证是发送端 key 的所有者到接收端 key 的所有者是保密的。至于怎样验证你要通信的对象的确是这个 key 的所有者,有两种普遍的模式:
1. 基于权威机构的证书,也就是 X.509 。 2. 基于面对面建立的信任网络,也就是 PGP 体系。 |
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 |
10
gkirito 2022-09-06 12:40:59 +08:00 via iPhone
想到 signal 好像就有这个功能,如果你不相信服务端发给你的 B 的公钥信息真假,可以双方发送自己的公钥二维码或者线下扫码确认验证
|
11
7RTDKSAK 2022-09-06 13:45:35 +08:00
我赞同 7 楼所说
1.如果是现实中认识地人之间加密通讯,可以考虑当面交换 KEY 2.但是如果和虚拟世界中地网友之间通讯,而且还需要加密,这样地情景其实不多,这种情况下通讯双方只能通过第三方来建立第一次联系,所以必然存在"选择哪一个第三方"/"该第三方是否可信"/"如果该第三方不可信又如何"等等一系列问题 |
12
zhengxiaowai 2022-09-06 13:55:51 +08:00
了解一下 signal protocol
|
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 见连接提到的更多技巧 |
14
Roanapur 2022-09-06 14:17:52 +08:00
可以做到。
你的担忧不是端对端加密的漏洞,而是中间人攻击的问题。 一切的安全措施,都有一些前提吧。 |
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 |
16
sy20030260 2022-09-06 14:38:35 +08:00
虽然但是,这里有个概念问题。
端到端加密和可信中间人是两个不同的问题。密钥不泄漏 or 不被伪造是端到端加密的“预设条件”,而非其“目标问题”呀。在满足密钥不泄露的前提下,可以做到除了发送端和接收端之外的其他节点无法获取明文信息,就是完备的端到端加密了 举个最极端的例子:即使是使用 Signal 通过当面交换公钥,但是用户在实际使用中使用了不受信任的物理设备,导致密钥直接在物理层面泄露了,这也会导致信息泄露发生。但这并不能说明 Signal 提供的端到端加密是假的或不完备的... |
17
ren2881971 2022-09-06 14:40:27 +08:00
可以用那个协同密钥。 客户端和服务端组合一起才能解密。
|
18
rekulas 2022-09-06 14:51:01 +08:00
“亦或借助 server 进行转发,server 俨然就是一个中间人的角色,在协商阶段把 A 、B 的密钥全都替换成 server 的。”
这个中间人的定义就不太准确,参考中间人攻击方式,server 要换密钥,那 client 就要信赖 server 才行,既然你都信任 server 了,那就相当于自己 hack 自己了。只要你只认可合法 client 的证书,server 没法攻击 |
19
dingwen07 2022-09-06 14:56:15 +08:00 via iPhone
|
20
nomagick 2022-09-06 15:00:05 +08:00
什么鬼都在瞎说八道一些什么,明明 2 楼就是正解
都没没听过 Diffie-Hellman 么, 在双方不直接发送密钥的前提下完成密钥交换。 你再仔细想想除了 server, 这条网络线路上所有交换机路由器不全部经手你的数据么,按你这么说加密根本没法做了 |
21
krixaar 2022-09-06 15:04:29 +08:00
了解一下 OMEMO ?
|
22
mokiki 2022-09-06 19:46:27 +08:00
内网的话可以扫描整个内网 ip 端口来连接,不需要电脑这样的 server 。此时交换机就是中间人,因你没法保证这个交换机不是含有两个网口的电脑。这种情况只有一楼的方法能保证互相信任。
至于 DH 什么的,也需要用安全的通道事先知道对方的公钥,或通过信任第三方获取对方公钥,典型应用就是 CA 证书体系的浏览器。我就不信有人能把电脑和浏览器的证书都删掉还能用 DH 交换出安全密钥。 |
23
rekulas 2022-09-06 23:50:34 +08:00
@nomagick 密钥交换只是其中一个逻辑啊,光有交换算法也没法通信,都说远了最简单的 https 通信就是一个非常安全的端端通信,在不自黑的情况下目前没办法破解
|
24
urnoob 2022-09-07 00:14:56 +08:00 via Android
可以,思科的 webex 应该是端到端加密的
|
25
iX8NEGGn 2022-09-07 00:29:15 +08:00 via iPhone
@nomagick 你不会天真认为 DH 算法能防止中间人攻击吧,中间人可以两端都骗,算出两端的密钥,最终解决方案就是和 TLS 一样,引入 CA 才能解决。
|
26
nomagick 2022-09-07 04:07:23 +08:00 via Android
|
27
akira 2022-09-07 06:08:19 +08:00
信任都是有基础假设条件的啊。
在 server 不可信的前提下,AB 之间连身份都无法信任了。 |
28
rekulas 2022-09-07 09:11:00 +08:00
@nomagick 那你仔细想一想,要求你确认的目的是什么?就是为了让你自己负责对方是否可信啊,那么问题来了
如果你没有第三方认证机构,你确认的时候怎么知道对方是否可信呢?如果是假冒的你也无法分别 如果你说你本地存储了一份信任服务器名单,那又有个新问题,信任名单是从哪里来的呢?如果你通过网络传输,那又陷入了中间人攻击的怪圈。如果你是直接提前协商写死的,那么既然都可以提前协商了还用 dh 干什么,直接写死每个服务器通信对应的加密 key 不就完了?所以说光是 dh 是无法解决端端通信的 |
30
dbolo123 2022-09-07 09:32:33 +08:00 via Android
@dbolo123 安全一点的做法可能是,都选否,然后通过其他方式获取对方公钥,配在自己服务器上,再去连
|
31
iX8NEGGn 2022-09-07 09:35:19 +08:00
@nomagick SSH 推荐的安全登录方式是证书登录,怎么就没 CA 了,密码模式确实没 CA ,但它就是这么的不堪,随时被中间人工具,你能用不代表它安全,只是没人攻击你罢了。
|
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 非常相似 |
33
rekulas 2022-09-07 11:13:21 +08:00
@nomagick ca 并不是信任服务器名单,它只是一个授信机构,也就是初始化的时候可能没有任何证书,唯一的共识就是-所有人都信任 ca ,然后进入通信环节,ca 通过各种认证向客户端办法证书,大家都信任,通信才能继续。
ca+密钥交换,可以实现在不可信网络中的可信通信,这正好是 op 的需求,也是 https 的基础原理 回到你的疑问-ssh 就没 CA ,照这么说没法用了 可以用,但是你的通信时在不可信网络中的不可信通信,通信中的任何一个中间设备都可以对你发起攻击 要说主要的漏洞,可能就是 ca 认证环节了,如果认证不够严格可能会被伪造证书,但鉴于其超低概率和高难度基本可以认为是足够安全的,毕竟我们的互联网就运行在这套理论上而且稳定几十年了 |
34
rekulas 2022-09-07 11:25:06 +08:00
@rekulas 补充一句,其实普通的 ssh 证书登录也是用了 ca 的,只不过 ca 是自己并不被系统信任,所以开始的时候会询问你是否信任。
完全不依赖 ca 呢?也是可以通信的,但是如上仍然是不可信通信 |
36
BloodBlade 2022-09-07 13:15:28 +08:00
ssh 直接回答 yes 是基于对服务器提供商的信任吧,如果提供商在第一次连接就进行中间人攻击,这时候直接回答 yes 不就中招了?
|
37
yhvictor 2022-09-07 13:46:36 +08:00 via iPhone
|
38
yhvictor 2022-09-07 14:42:20 +08:00 via iPhone
如果区块链可信的话是可行的。
只要登登记 id 和公钥就行。 比如说张三李四登记了。 那么张三一定能发出一条只有李四才能解密的信息。 不过: 李四能不能收到要看网络上让不让传(某墙),或者信息也上链。 |
39
rekulas 2022-09-07 15:03:36 +08:00
@yhvictor 确实,你说的对,如果提前拷贝了 ssh 公钥,这种情况无法进行中间攻击。但是这又回到了最早的情形-既然都可以通过某种方式将公钥可信的传递到服务器,那么有没有密钥交换都无所谓,端端通信跟 dh 没关系了。这个我是针对 nomagick 的回复说的。
我也是做区块开发的,至于区块链我跟你看法也一样,区块链本身协议无法提供可信保障,现有的区块链其实都存在这个漏洞的,只不过区块链中间人攻击几乎没有什么收益,而且节点多攻击成本也高-有那能力还不如 51 攻击。 公钥加密-解决不可信网络的可信通信(如 https) 私钥加密-解决不可信网络的身份认证(如区块链) |
40
BloodBlade 2022-09-07 17:07:26 +08:00
@yhvictor 我的意思是,公钥一般是在购买服务器前先传到云服务提供商,购买服务器后再由提供商写入到服务器上,这个过程中公钥会在提供商中经过一次。如果先开服后上传公钥的话,也要通过密码连接或者提供商的后台来传上去,同样也存在被提供商利用的可能性。
|
41
daBig 2022-09-09 17:58:02 +08:00
搜一下 E2EE ,DH 秘钥交换算法就知道了
|