使用SSL感到安全吗?再想想。
最近,我们听到了很多关于我们对公共二进制存储库的信任的讨论。例如,Maven Central,一个由Sonatype维护的流行的遗留存储库,最近受到了一次成功的MITM攻击。作为回应,Sonatype设置了对central的https访问(取消了为使用SSL向Apache基金会捐赠10美元的要求)。这对世界上数百万的maven安装没有影响,它们将继续通过http访问maven Central,除非手动重新配置,但有趣的问题是这就够了吗?
虽然SSL在保证下载文件的完整性方面很重要,但它并没有说明存储库中文件本身的完整性。Maven Central和其他遗留存储库建议您盲目信任的存储库本身的唯一验证机制是随文件一起上传的签名文件集。有趣的是,现代的存储库,比如RubyGems.org,npm-registry和Bintray不要强迫你在文件上签名。让我们试着理解其中的原因。
这是tl,博士如果你需要的话。
SSL访问是否足以让我们感到安全?
要回答这个问题,让我们考虑一下Maven Central。这是一个使用SSL并使用PGP签名“保护”文件的存储库。从理论上讲,这些签名文件强有力地标识了签名者(假设jar文件和签名都是通过SSL提供的)。但真的是这样吗?
让我们看看它是如何工作的:
- 作者使用了gpg工具生成用于标识的对。
- 然后,作者将公钥上传到可信密钥服务器(其中之一)麻省理工学院,SKS OpenPGP公钥服务器或PGP全局目录).
- 任何想要下载包并验证其完整性的人都会对其中一个服务器进行签名检查,并获得作者的唯一且经过验证的身份。

让我们运行几个实验,看看“安全的”Maven Central的维护到底有多安全。
以下是Sonatype的最新版本:nexus-core-2.8.1-01。
我们下载一下,看看签名是怎么写的,导入签名者的公钥后:
> gpg nexus -核心2.8.1发布- 01. jar.ascgpg:签名于2014年5月27日18:00:54中部夏令时使用DSA密钥ID 8DD1BDFDgpg:来自“Sonatype, Inc. (Sonatype发布密钥)”的良好签名 gpg:警告:此密钥未经过可信签名认证!gpg:没有迹象表明签名属于所有者。主键指纹:2BCB DD0F 23EA 1CAF CC11 D486 0374 CF2E 8DD1 BDFD
哇!发生了什么事? !"没有迹象表明签名是主人的" ?!
等一下。这是否意味着任何人都可以生成对Sonatype, Inc. " (Sonatype释放键)
这是一张很棒的图片:

根据“可信”密钥服务器,所有这些签名都属于德国诗人海因里希·海涅。我觉得这不太可能因为他去世很久了1。
让我们再运行几个测试(想想看,也许只有Sonatype不能生成“真正可信”的签名):
这是一个签名Eclipse工件:
> gpg aether-1.0.0.v20140518-source-release.zip.ascgpg:签名于2014年5月18日12:54:52中部夏令时使用DSA密钥ID A7FF4A41gpg:来自“Benjamin Bentmann (CODE签名密钥)”的良好签名 gpg:警告:此密钥未经过可信签名认证!gpg:没有迹象表明签名属于所有者。主键指纹:BA92 6F64 CA64 7B6D 853A 3867 2E20 10F8 A7FF 4A41
一样了!
> gpg jmh-core-0.9.5.jar.ascgpg:中央夏令时07/24/14 13:53:36签名使用RSA密钥ID 060CF9FAgpg:来自“Evgeny Mandrikov (CODE签名密钥)”的好签名 gpg:警告:此密钥未经过可信签名认证!gpg:没有迹象表明签名属于所有者。主键指纹:A413 F67D 71BE EC23 ADD0 CE0A CB43 338E 060C F9FA
Evgeny Mandrikov是谁?甲骨文的员工?不。他为什么用gmail?让我想想,也许Sonatype在让他进入Maven中心时预先验证了他?他和甲骨文公司建立关系了吗?什么也没有,一个问题也没有。“我与Oracle无关,但仍然想发布OpenJDK工件!”“好的,去吧。”您能信任他为您提供真正的OpenJDK工件吗?不确定2。
你懂的。您不能信任那些自生成的密钥对。而且受信任的密钥服务器自己也承认这一点!这里有一段引自PGP全局目录密钥验证策略:
……总有一种风险,即PGP全局目录中经过验证的密钥实际上并不属于看起来拥有它的人。虽然目录中的验证机制适用于许多用途,但您应该努力使用其他机制……
这就是现代软件库的样子Bintray和GitHub做的。但我们很快就会讲到。
但是WoT呢?
”啊,有人会说,这是因为您对PGP签名的工作原理一无所知!你需要建立一个信任网有了签名者,瞧,信息不见了!”
虽然这在技术上是正确的,但在我们的上下文中却没有什么意义。
WoT适用于pgp签名的原始用法-对您直接认识的人或通过您的联系人间接认识的人的内容进行身份验证。例如,它在签署电子邮件时效果很好。你可能会收到来自第一、第二或第三圈朋友的电子邮件,但几乎不会收到来自完全陌生的人的电子邮件。对于来自Internet存储库的包,这个概念完全被打破了。开发人员亲自认识一个包的创建者的可能性几乎为零,即使是间接地联系到一两个级别。同样适用于包的创建者。作为一个作者,你不知道谁会使用你的包。你只能希望他们是一群你不认识的陌生人: - d。
我很好奇。告诉我如何在不使用MITM的情况下恶意上传伪造的工件到Maven Central !
冗长,但很直接:
- 发明一个假的身份(用一个假的,但功能正常的电子邮件地址)。
- 为它生成一个密钥对。
- 上传到公钥服务器(这就是需要您的电子邮件的地方)。
- 遵循该指南。最棘手的部分是伪造一个关于您的工件的故事,以便通过Sonatype JIRA在oss.sonatype.org上设置您的帐户。嗯,要有创意!
- 在几个小时(或几天)内,您的工件将到达Maven Central。如果你编造的描述看起来足够真实,他们就不会问你任何问题。在上传和发布文件的过程中,Sonatype将检查您签名工件所用的签名是否与您用于oss.sonatype.org帐户的电子邮件相匹配。当然,它们是匹配的。
- 到Mazal Tov !你的假藏物现在在Maven中心。从那里,它们将被Maven安全地(!)通过SSL下载到您的受害计算机。
容易吗?嗯,不完全是。看来中间人攻击更容易。但这就是将一个jar添加到Maven Central所需要的。
可行的吗?绝对的。
但是Bintray有什么不同呢?
我们意识到,在现代社会,身份盗窃是最常见的犯罪之一,你不能盲目地相信网络身份。因此,像许多其他服务一样,我们建议您根据社区对作者互联网身份的信任来评估任何特定内容(在我们的情况下是一个罐子)的可信度。
我的意思是:
假设您想下载Groovy。在这里。让我们看看如何在Groovy二进制文件中建立信任:
- 你可以看到a的链接网站和GitHub。
- 你可以看到这个包属于一个组织:Groovy。您可以清楚地看到成员列表,并检查每一个成员。
- 这是Guillaume Laforge。
- 看看他的推特账号——近8.5万粉丝。
- 这是他的博客,都围绕着Groovy。
- LinkedIn吗?看起来不错。
所以,你能信任他吗?可能。他是Groovy组织的管理员,因此他的声誉是组织及其中的文件是可信的保证。你可以走了。或不呢?
这取决于你!我们给你信息。你决定你是否可以相信它。
但Maven只是走出去,带来了东西!
打造一个安全的你必须使用内部二进制存储库管理器:
- 安装它。
- 配置一个“脏”存储库和一个“干净”存储库。
- 脏存储库应该能够代理工件的远程来源,从而使您能够很好地了解工件生产者的身份(而不仅仅是一堆带有自生成签名的文件)。
考虑代理BintrayJCenter而不是Maven Central。JCenter是Maven Central的超集,因此查找包不是问题。 - 干净存储库是没有Internet访问的本地存储库。
- 脏存储库应该能够代理工件的远程来源,从而使您能够很好地了解工件生产者的身份(而不仅仅是一堆带有自生成签名的文件)。
- 配置您的构建工具(Maven?),以便能够针对它们中的任何一个进行构建。
- 使用“沙箱”(例如vm)对脏存储库运行“脏”构建。它的缓存将被构建所需的所有构件填充。
- 检查这些工件的发布者的身份(记得选择一个二进制存储库,它可以生成用于每个构建的依赖项列表)与您所拥有的有关它们的信息(如您所理解的,最好不只是自签名签名)相比较。
- 将您信任的构件提升到干净的存储库(记得选择带有删除处理存储这给了你自由和即时的“移动”操作)。
- 现在,您可以安全地构建干净的存储库了!
以下是总结(又名tl;dr):
- SSL是验证您信任的文件是否安全地从服务器传输到您的计算机的重要方法。
- 不要让SSL给您一种错误的信任文件来源或作者的感觉。
- 不要盲目地相信自己发布的签名。您可以为任何身份生成签名,用它对任何文件签名并将其上传到Maven Central。
- 选择一个支持并鼓励网络身份验证的平台。查看作者并自己判断。
- 使用二进制存储库管理器来发现和控制所需的工件(并明智地选择它)。
了解更多关于JFrog和Sonatype比较起来怎么样。
1一个gpg工具与PGP签名一起工作是在杜塞尔多夫海因里希海涅大学。为了纪念已故诗人海因里希·海涅,该大学以他的名字命名,该工具中的所有默认值都初始化为海因里希·海涅,期望人们可以用自己的详细信息替换它们。显然,这不起作用。人们只是通过设置进入-进入-进入,为可怜的德国人生成了几十对密钥,说明了“真实的”,自生成密钥对的荒谬。
谢谢,海因里希!
2事实上,你可以。Oracle不分发OpenJDK的二进制文件,Evgeny是自愿的,并被OpenJDK提交者授权为他们做这件事。
但你不熟悉叶夫根尼就能知道吗!不,你不能。