shadowsocks / shadowsocks-org

www.shadowsocks.org
MIT License
882 stars 541 forks source link

关于一些基本问题的讨论 #64

Closed riobard closed 6 years ago

riobard commented 7 years ago

这串讨论源起于 @hellowingy 在 Twitter 引用 @zhuhaow 的文章《某些网络工具的安全性》。考虑到最近 Shadowsocks 的一些改动引起了不少的争议,有一些基本问题需要理清楚,才好让大家(至少是相关项目的开发者)对这些问题有一个正确的认识。

riobard commented 7 years ago

先提一个最基本的问题:Shadowsocks (后文简称 ss)有没有(以及要不要)提供密码学意义的安全?

密码学意义的安全具体指保密性 (confidentiality)、完整性 (integrity)、真实性 (authenticity)。

zhuhaow commented 7 years ago

首先我不觉得integrity和authenticity有什么实质上的区别。 其次它们的必要性在ss中是值得怀疑的。

riobard commented 7 years ago

《某些网络工具的安全性》中,@zhuhaow 认为

(ss 的) Confidentiality 从来都没有出过问题, Integrity 可以说在设计之初就并没有列入考量(这并没有问题,我懒得展开了,但是篡改数据没有任何意义), Authentication 其实是通过 TYPE 来实现的,也是出问题的地方所在

这里我认为是不对的。事实上 ss 在设计之初并没有考虑密码学意义的安全,因此使用 table 方式做了简单的替换,目的仅仅是为了绕过内容过滤审查。后来换用流加密(stream cipher)也没有考虑保密性的问题,因而保密性是有缺陷的,这个问题在 #36 里有讨论。

riobard commented 7 years ago

我不觉得integrity和authenticity有什么实质上的区别。

这确实是个比较 tricky 的问题。可以参考 PGP 的解释 http://www.ac.uk.pgp.net/pgpnet/secemail/q4/node4.html

其次它们的必要性在ss中是值得怀疑的。

这个就是要不要的问题。

zhuhaow commented 7 years ago

有点事所以回的比较慢。

Confidentiality 这个问题其实是一个大家过于关注的问题了。事实上,也并没有什么实质的理论指出64 bits的nouce真正的不安全。

通常在加密这个领域大家说到可能weak,甚至是weak的时候,往往指的是,如果CIA/FBI/Mossad/whatever 在想的情况下,在可预见的未来,似乎有可能运用几年/月的运算时间破解出数据的内容。对于普通人而言,其实就是没有任何安全问题可言。

zhuhaow commented 7 years ago

当然table不安全,很难说这是加密了,但是自RC4-MD5之后的方法,没有任何理由说它们在实际的使用中会不安全,当然我坚决支持在性能可接受的情况下使用最新的加密方法。事实上,我不想为兼容性妥协任何安全性。

zhuhaow commented 7 years ago

说回integrity的问题,无所谓定义如何,我来定义我们想讨论的就是,是否有必要能够验证数据是由一个知道pre-shared key的用户发来的,且未经篡改。

zhuhaow commented 7 years ago

在谈integrity的必要性之前,我先说攻击者是否有兴趣篡改,或者伪造数据。 在我文章里提出的解决方案下,CCA是不可行的(至少我设计不出方案来)。那么攻击者伪造数据没有任何意义,他只可能想要篡改数据。

zhuhaow commented 7 years ago

那么对于攻击者而言,首先他要决定的是如此大量的数据面前,他要篡改什么数据。 显然不能随机选,那就必然已知这是ss的流量了。 在这种情况下,如果攻击者不希望用户正常使用,显然封服务器是最简单好用的策略,看不出任何篡改的意义。

zhuhaow commented 7 years ago

接下来我们再看,ss协议本身,是否有integrity的需求。 ss是做什么的呢,是用来传输数据流的,那只是一个代理的协议。我们可以看到,http代理也好,socks4/4a/5代理也好,均没有任何关于integrity的验证,尤其是socks4/4a/5这个数据流代理也没有。这是为什么呢?因为数据流的integrity是应当由application在需要的时候完成检查的。

riobard commented 7 years ago

事实上,也并没有什么实质的理论指出64 bits的nouce真正的不安全。

这个陈述过于模糊了。64-bit nonce 安不安全取决于 nonce 是如何生成的,以及相关的 key 是如何使用的。初版 ss 使用 PSK 配合随机 64-bit nonce 的方式确实是(密码学意义)不安全的。这个有客观的方式可以度量。这个在 #40 里面有讨论。

通常在加密这个领域大家说到可能weak,甚至是weak的时候,往往指的是,如果CIA/FBI/Mossad/whatever 在想的情况下,在可预见的未来,似乎有可能在几年/月内破解出数据的内容。对于普通人而言,其实就是没有任何安全问题可言。

我认同这个大前提。但是因为这里讨论的是密码学意义的安全,我觉得还是有必要遵循主流的定义。至于说「不安全也影响不到某个个体,所以对这个个体是安全的」这种说法比较容易搅乱定义,不利于展开讨论,我倾向于反对这种说法。我们可以说「的确不安全,但影响不大」。

zhuhaow commented 7 years ago

为什么这么说呢?integrity的目的是什么,是为了确保中间通路的各个节点不能够修改数据。 如果application有这项需求,那么它自己就应当实现这一点,因为application是不可能会设想传输是通过一个安全代理完成的。如果它没有,它自然就不在意这个问题。 最常见的确保integrity的方法就是SSL/TLS,很显然,在意integrity的(理论上应该是所有网站,现实么),应当自行使用SSL/TLS来完成数据传输,在这时,ss并不会提供任何而外的价值。 对普通数据,设想即便ss提供了integrity的保障,数据依然要明文由ss服务器通过若干中间节点的传输,中间依然可以发生篡改,既然application不在意,ss提供的保障其实也没有起到意义。

zhuhaow commented 7 years ago

这个陈述过于模糊了。64-bit nonce 安不安全取决于 nonce 是如何生成的,以及相关的 key 是如何使用的。初版 ss 使用 PSK 配合随机 64-bit nonce 的方式确实是(密码学意义)不安全的。这个有客观的方式可以度量。这个在 #40 里面有讨论。

设想我有一任意快的计算机,那么所有加密技术都是没有区别的。加密的目的就是在于使得破解所需要的资源在当前和可预见的未来是不足够的。而当前的很多deprecated的加密算法其实也还是满足这一点的。

不过我依然建议使用更强的加密算法。只不过这个问题对普通用户完全不构成问题而已。

zhuhaow commented 7 years ago

其实,ss这些代理协议,完全可以看作是TCP流的代理版,从来没有听说有人想要检查TCP包的integrity(checksum都被取消了),因为本身这就不是TCP需要关注的问题。

riobard commented 7 years ago

@zhuhaow 我先把加密的问题理一下哈,等下再说 integrity 的问题。

当然我坚决支持在性能可接受的情况下使用最新的加密方法

其实目前的两种 AEAD 的性能挺好的。在搭载 AES 硬件加速的机器上 AEAD_AES_128_GCM 的性能显著高于 AES-128-CTR/CFB。没有 AES 硬件加速的机器上 AEAD_CHACHA20_POLY1305 如果利用了较新的 CPU 指令集也能做到非常高的效率。

zhuhaow commented 7 years ago

ss 的 integrity 的意义就和我用UDP实现一个 reliable, ordered, and error-checked protocol一样无谓,这个gfw完全没有关系。 我已经说过了,篡改不会发生,因为没有意义,一件不会发生的事情为什么要未雨绸缪。

你看,我就从来没有设想过有钱了以后如何生活……

zhuhaow commented 7 years ago

而且如果要“防止服务器行为检测“,那ssr真的做的好的不知哪里去了(虽然我觉得没有意义),就算有AEAD也没有起到任何obfuscation的作用啊。

zhuhaow commented 7 years ago

以上两条评论是针对一些被删除了的回复的……

bigboyq commented 7 years ago

我觉得ss的目的就是翻墙,这个是第一要务 如何更好的翻墙? 1.ss协议去特征化 2.ss内容在特征明显的时候可以降低访问对象的特征 其他的所谓 1.加密性问题,应该交由app层的协议去保障,例如tls 2.完整性问题,其实aead已经解决

我觉得现在的关键是如何在3.0的基础上降低特征即可

  1. 8位随机IV 加数据流的格式 2.检验失败不返回断开

个人建议,在验证失败时返回随机结果,由客户端进行结果检验后判断后续处理就可以了

至于由此引发的慢速攻击,cc攻击等,交由防火墙,策略等按常规处理

riobard commented 7 years ago

说回integrity的问题,无所谓定义如何,我来定义我们想讨论的就是,是否有必要能够验证数据是由一个知道pre-shared key的用户发来的,且未经篡改。

这里稍微有点问题,已经是 integrity + authenticity 两个要求了。Integrity 指的是作为密文的接受方能确保密文未被不知道 PSK 的第三方篡改过。而密文的接收方能确保密文是由知道 PSK 的人发过来的则是属于 Authenticity 的范畴。Authenticity 暂时不是重点,待会再说。

Integrity 的问题最初是由 @breakwa11 提出可以通过篡改密文中 type 对应的那个字节然后观察服务器的反应,根据反应结果有极高的可信度判定是否为 ss 协议,并且提供了可用的测试工具。这个便是因为 Integrity 的缺失导致的行为侧漏 😂,因为服务器端在 3/255 的概率上不知道密文被篡改了。

很多人认为这个问题根本不需要解决,攻击者有那个空闲来探测不如直接封掉 IP 算了。在目前的情况下的确是可以这样认为……不过毕竟泄露行为不是什么好事吧,于是有了 OTA 这个补丁出现。然后就是如 @wongsyrone 所言这属于自己造的轮子不圆,不如用现成的、理论基础更完备的 AEAD,所以有了 SIP004 (#30)。

bigboyq commented 7 years ago

至于obfs 我觉得 ss over tls就可以了,甚至iv都可以基于tls本身特定串hash生成 不要试图在一个翻墙工具里面解决所有问题

zhuhaow commented 7 years ago

这里稍微有点问题,已经是 integrity + authenticity 两个要求了。Integrity 指的是作为密文的接受方能确保密文未被不知道 PSK 的第三方篡改过。而密文的接收方能确保密文是由知道 PSK 的人发过来的则是属于 Authenticity 的范畴。Authenticity 暂时不是重点,待会再说。

你仔细想想这两件事是一件事,就是数据是由有key的人生成加密并发过来的。

riobard commented 7 years ago

@zhuhaow 不是呀,篡改数据不需要有 key。

riobard commented 7 years ago

我说一下我对「ss 有没有提供密码学意义的安全?」的理解吧:

  1. 初版 ss 没有提供保密性、完整性、真实性,因为安全根本不是设计目标。
  2. ss 采用 SIP007 (#42) 后提供了保密性和完整性。真实性则取决于是否给多个用户共享同一个密码。至少在设计理念上 ss 是不鼓励多个用户共享密码的。
riobard commented 7 years ago

从来没有听说有人想要检查TCP包的integrity(checksum都被取消了),因为本身这就不是TCP需要关注的问题

其实是有必要的……比如 TCP RST 攻击就是因为 integrity 缺失导致的 😢 SIP005 (#32) 试图解决这个问题,但在应用层面并不可行只好作罢。

riobard commented 7 years ago

总体来说, AEAD 给 ss 带来的好处是大大提高了安全性,并且采用成熟的第三方库实现,避免了自己造轮子可能带来的潜在问题,同时又提供了极佳的性能和兼容性(只需要支持已经成为行业标准的 AEAD_CHACHA20_POLY1305)。我们应该鼓励客户端和服务端的开发者尽可能支持 AEAD 的加密方式。

至于其他的如混淆、伪装等问题,则应该通过 SIP003 (#28) 的插件机制实现,在保留核心功能不变的情况下提供更加灵活多变的组合以应对用户所处的不同的网络环境。

hellowingy commented 7 years ago

”我不管,反正它很好“ 哈哈哈...

yjqiang commented 7 years ago

个人以为加密方式只是作为一种混淆方法存在,保密性自然的有上层的tls保障。甚至像 @breakwa11做的那样,认为混淆性已经足够好,加密还使用none。(https://breakwa11.blogspot.sg/2017/04/proxy-protocol-analyze.html ”一个小插曲,有个网友做了个实验,使用auth_aes128_md5协议,不带混淆,不带加密,直接祼跑超过了80G流量,还是啥事都没发生。“)

从这个方面来讲,我认为加密甚至可以不存在,混淆的意义远远大于保密。

riobard commented 7 years ago

@yjqiang 然而并非所有网站都是 TLS 连接。对于很多人而言,安不安全并不要紧。如果其他条件保持不变的话,安全总比不安全要好吧?在更好的基础上去解决混淆和伪装的问题,总强过在不牢靠的基础上修修补补。两者并不矛盾。

yjqiang commented 7 years ago

同意,两者不矛盾,而且也同意本项目的混淆设计思路,去把混淆与安全区别开。 但是最近的obfs-simple更新中并没有多少混淆方面的加入,利用已经造好的tor的混淆思路是好的,但似乎还远远没完成,而且在各平台的客户端也都明显基本都没有跟上。 个人的意见只是从最近项目发展来看,似乎过于强调了安全。希望今后可以把大部分精力投入到混淆的方面。

zhuhaow commented 7 years ago

AEAD无关痛痒(不论是性能损耗还是安全性加强),我只是想指出意义太有限而已。

所有所谓的安全性增强都只是幻象,因为原本的安全性就没有任何的问题,好比100米的墙已经够高了,非要加高到800米,我只能说未尝不可,但是太没有意义了。

在某种意义上ssr做的事情确实更有实际意义(但很多只是比没意义好一点点的有意义,所以很多我也懒得支持)。

除非有涉及到:

  1. 我设计的方法依然可以进行CCA
  2. 篡改数据对中间人是有意义的或者中间人能够进行对用户有损害的篡改(相较于直接封服务器而言)
  3. 在 confidentiality 上有漏洞 不然我不再回复了。

写文章本就只是想澄清一些大家的误解,并没有想说新算法没有更“安全”。 大家想要追求不同程度的“安全”,所以只能求同存异了。但是至少基本事实是不能搞错的。

希望通过更多的讨论能让大家理清一些事实,毕竟真正的讨论太少,玄学太多了。

riobard commented 7 years ago

@yjqiang 底子要打好嘛,不然以后再改成本就更高了。

我理解 obfs-simple 主要是为新的插件机制做个 demo,并没有打算提供非常完善的混淆支持。有兴趣的开发者应该利用这个项目的模版开发新的或者移植已有的 Tor 的 PT 插件。

riobard commented 7 years ago

大家想要追求不同程度的“安全”,所以只能求同存异了。但是至少基本事实是不能搞错的。

是的,也是这串讨论的本意。

有个小异议就是 3. confidentiality 事实上是有漏洞的,不过就目前的情况看来对个人而言影响不大。

breakwa11 commented 7 years ago

除非有涉及到: 我设计的方法依然可以进行CCA

算了,我实在忍不住了,我就说一句, @zhuhaow 你文章中不使用 TYPE 1 和 4,只使用TYPE 3以及验证域名合法性的方法,我还真有主动探测方法,不过会依赖于具体实现。不只你,还有其它人提到过这个方法,但我意识到这个问题所以我懒得去改动原协议了(用TYPE3还浪费更多的字节),做个协议包装来得更彻底 至于SSR有没有意义,时间可以去证明的,不过现在还没做到最好,还有更好的,可能你认为这不过是over doing

atYuguo commented 7 years ago

就个人的经验来看,我使用 SS 主要关心两个层次:

  1. 攻击者不应识别出我在使用 SS;
  2. 攻击者不应识别出 SS 中正在通过的流量是什么。

首先两者都是必要的:极端情况下,如果只关心第一条,那么只要把 SS 实现为一个“空协议”,即不干任何事直接通讯(或者最多 redirect 一下端口),那么自然不存在识别出 SS 的可能。但第二条就完全失效,也无法绕过审查。如果只关心第二条,那么已经存在的 VPN 比如 Openvpn 就是例子。

理想情况下,两者都能实现,那对我的用途来说,也是充分的。不过实际情况下, SS 总是两个层次间妥协的产物。

关于最近加入的 AEAD,虽然起因是为了修补第一条中的漏洞,但长远来看,AEAD 对于第二条意义更大,毕竟由 @breakwa11 提出的攻击没有理由不能对信道内的特殊协议起作用。换而言之,对第二条好的加密是必须的,所以我支持最近安全性方面的更改,与其修修补补,不如直接上 AEAD 这样成熟的工具,既不伤害第一条(实际上还避免了由 @breakwa11 提出的问题),又为第二条打下了坚实的基础。实际上要我来的话就直接推出个新版本,然后只剩下 AEAD,免得麻烦:)

zhuhaow commented 7 years ago

@breakwa11 TYPE 3 的问题其实我也想到了,不过这个完全依赖具体实现几乎无法作为规则使用,尤其是实现如果结合非法请求延迟断开就不可能进行检测,我实现一个肯定就查不出来(就算给你重放的机会)。更何况何必要这么检测,ss 的流量特征本身就足够明显,ssr的那些混淆还好,而且AEAD本身的特征不是更明显了,就算ss再加上简单的混淆,还不是大量莫名的随机字节,一样一眼就看穿了。

额外字节什么的完全无影响,新协议那么多字节都加了还差这inet_ntoa多出来的那几个么。

SSR那些更多理论上的安全性部分,一个本来就安全的东西理论上的安全性的增强对用户又有什么意义呢。

我并不否认这些东西在理论上更安全了(不过比安全更安全也还是安全而已),只是单纯普及一点讨论的基础罢了。如果大家很喜欢理论安全性就去追,我也没啥意见,我也喜欢理论上的安全性,但是别总是要来讲的原来的东西有多"不安全"。

一讨论起来总有人来就是ss的原版安全性有问题,能不能不要用忽悠的方式,大大方方的告诉大家到底那里不安全(比如TYPE 1 4的bug的提出的就很好啊,直接说,这个bug也丝毫没有影响过ss的传输安全性本身,但是后来也还是被广泛误解了),什么级别的计算机才可能进行破解?别的不说,至今为止有一人能把ss+RC4-MD5的流量解密出来么,准备用什么计算资源?更不要说其他了。

比如楼上上的帖子,sorry,不是挂人,你正好发了我就举个例子,第二条真的从来都不是问题,AEAD也没有任何帮助

就是这种话太多了,太多人以为旧协议一刻也用不得了,所以我才写这篇文章。

zhuhaow commented 7 years ago

@ccsexyz 在重放的情况下如果实现的不好还是可以的,成功率不高,而且还要求是重放就是了。

ccsexyz commented 7 years ago

@zhuhaow 重放可以用 iv cache 来解决啊

zhuhaow commented 7 years ago

@ccsexyz 他们对安全的要求比较高(是理论级的)。

假设对你很有兴趣并且愿意花很长的时间反复尝试呢?cache总是要满的。

riobard commented 7 years ago

@zhuhaow 原版 ss (密码学意义的)不安全是客观事实,没有必要强行洗白,这是我觉得你文章有问题的核心。你让 @clowwindy 出来说他也不会认为当初的设计目标和安全有半毛钱的关系。

撇开 @breakwa11 的探测方式不说,nonce re-use 的情况下 XOR 一下两个密文就可以了,根本不需要多大的计算资源(不过需要一些存储)。

zhuhaow commented 7 years ago

我说了啊,到底那里不安全你说出来啊,不要东拉西扯的……

没有那个实现会有nonce re-use吧。

zhuhaow commented 7 years ago

重放时候用的就是合法时候的IV啊,关键在于理论上早晚有一天cache会满的。 老实说通过cache来防止replay我也是很不喜欢的。

riobard commented 7 years ago

没有那个实现会有nonce re-use吧。

你肯定没看之前的讨论。建议先阅读 https://github.com/shadowsocks/shadowsocks-org/issues/36#issuecomment-277496869

我相信一个靠谱的实现不会主动 re-use nonce,所以才使用随机生成对不对?假设我们用最完美的随机数生成器,只有 64-bit nonce 的 chacha20 会在 2^32 内出现 nonce re-use。更何况实际上很多人在低端路由器上跑 ss,硬件本身提供的随机数生成器就质量可疑,在 entropy 不足的情况到底多久会 nonce re-use 其实根本没有理论值那么乐观。

zhuhaow commented 7 years ago

嗯,终于步入正题了。

2^32次是和IPv4的地址一样多的,这是很多的。 随机数发生器是这样的…… 首先呢,路由器这种等级应该是不够格配硬件随机发生器的。 再次,最重要的,随机数发生器(软件)的质量低往往不是指他们会重复,事实上恰恰相反,随机数发生器的算法往往是在它的一个cycle内不会重复的!这也恰恰是随机发生器质量不高的一个重要例证……不过这恰好是我们要的……因祸得福

最后,我们就假设有一个中间人这么闲吧,他也不知道你的数据是什么,但是他兴致勃勃的把他们全部记录下来,至少也要几百万条甚至更多,然后找出开头一样的,XOR,BINGO,他得到了某两条明文的XOR,然后……然后又怎么样了,这数据有多重要以至于有人会能够分析这两个XOR的结果得到原文然后得出有价值的信息影响用户的安全么。理论上也有可能。

理论上都没错,但是如果我,我就会写完上面一段再告诉大家,这个算法在业界是被一些人认为weak的。

riobard commented 7 years ago

你看,所以我说讨论的时候不能太发散。本来就是为了讨论密码学意义的安全,上面已经说得很明白了,原版 ss 就是不安全的(因为设计目标就没考虑安全)。这是客观事实。但是这种不安全的后果怎样呢?其实也不会怎样 😂

zhuhaow commented 7 years ago

我写文章就是要告诉大家,不会怎么样。

我只是希望以后大家都能先告诉大家,不会怎么样,但是我们还是可以更安全。

riobard commented 7 years ago

还有一点要说明的是,ss 使用 chacha20 的方式不安全并不等于 chacha20 本身不安全;反过来,chacha20 安全并不等于 ss 使用 chacha20 的方式安全(chacha20 可以换成任何加密方式)。这才是很多人跟风起哄、玄学四起的本因。

而作为开发者,我们要避免给用户过多的选择导致各种玄学。给出一个基础扎实的默认构造让大家用就好了,用户没有必要选来选去。AEAD 就是要解决这个问题:性能不错、足够安全。

riobard commented 7 years ago

@zhuhaow 那你不能在文章里面说原始的构造是安全的呀,这样很容易产生误解的 😂

zhuhaow commented 7 years ago

原始的构造依然是安全的啊,到底是哪点不安全了?

zhuhaow commented 7 years ago

理论上的东西没有实际的可能性啊