10

Amazon 在 1.3.21 版本中“升级”了其 AWS Java SDK 中的 SSL 安全性。在使用 Amazon 的 AWS Java API 时,这会破坏对名称中带有句点的任何 S3 存储桶的访问。我正在使用 1.3.21.1 版本,该版本截至 2012 年 10 月 5 日。我在下面的回答中提供了一些解决方案,但我正在寻找解决此问题的其他方法。

如果您收到此错误,您将在异常/日志中看到类似于以下消息的内容。在此示例中,存储桶名称为foo.example.com

INFO: Unable to execute HTTP request: hostname in certificate didn't match:
       <foo.example.com.s3.amazonaws.com> != <*.s3.amazonaws.com>
       OR <*.s3.amazonaws.com> OR <s3.amazonaws.com>
at org.apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.java:220)
at org.apache.http.conn.ssl.StrictHostnameVerifier.verify(StrictHostnameVerifier.java:61)
at org.apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.java:149)
at org.apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.java:130)
at org.apache.http.conn.ssl.SSLSocketFactory.connectSocket(SSLSocketFactory.java:390)

您可以在 AWS S3 讨论论坛上查看此问题的文档:

https://forums.aws.amazon.com/thread.jspa?messageID=387508

亚马逊对此问题的回应如下。

我们应该能够通过对具有这种命名模式的存储桶使用较旧的路径样式寻址方法(而不是较新的虚拟主机样式寻址)来解决此问题。我们将开始修复并确保我们的内部集成测试具有包含句点的存储桶名称的测试用例。

任何解决方法或其他解决方案?感谢您的任何反馈。

4

2 回答 2

9

原文:2012 年 10 月

事实证明,亚马逊在 2012 年 9 月下旬“升级”了 S3 上的 SSL 安全性。当使用亚马逊的 AWS Java API 时,这破坏了对名称中带有句点的任何 S3 存储桶的访问。

这是不准确的。S3 的 SSL 通配符匹配与 S3 于 2006 年推出时相同。更有可能的是 AWS Java SDK 团队启用了对 SSL 证书的更严格验证(很好),但最终破坏了与 S3 的 SSL 相冲突的存储桶名称证书(坏)。

正确的答案是您需要使用路径式寻址而不是DNS 式寻址。这是解决 SSL 证书上通配符匹配问题的唯一安全方法。禁用验证会使您面临中间人攻击。

我目前不知道 Java SDK 是否将其作为可配置选项提供。如果是这样,这就是你的答案。否则,听起来 Java SDK 团队说“我们将添加此功能,然后添加集成测试以确保一切正常。”

更新:2020 年 10 月

AWS 已宣布不推荐使用的路径式寻址将在不久的将来消失。AWS 的建议是使用与 DNS 兼容的存储桶名称,这意味着没有句点(以及其他一些内容)。S3 的某些较新功能需要与 DNS 兼容的存储桶名称(例如,加速传输)。

如果您需要一个包含句点的存储桶名称(在不久的将来也不允许新存储桶使用),如果您想通过 HTTPS 访问它,我最好的建议是在它前面放置一个 CloudFront 分配。

于 2012-10-06T02:29:51.297 回答
6

亚马逊发布了 1.3.22 版本解决了这个问题。我已经验证我们的代码现在可以工作了。引用他们的发行说明:

现在可以通过 HTTPS 再次正确寻址名称中包含句点的存储桶。

除了等到亚马逊发布新的 API 之外,我还可以看到一些解决方案。

  1. 显然,您可以回滚到 AWS Java SDK 的 1.3.20 版本。不幸的是,我需要 1.3.21 中的一些功能。

  2. 您可以替换org.apache.http.conn.ssl.StrictHostnameVerifier类路径中的 。这是一个hack,但是我认为它将删除对 Apache http 连接的所有 SSL 检查。这是对我有用的代码:http: //pastebin.com/bvFELdJE

  3. 我最终从 AWS 源 jar 下载并构建了自己的包。我将以下近似补丁应用于HttpClientFactory源。

    ===================================================================
    --- src/main/java/com/amazonaws/http/HttpClientFactory.java     (thirdparty/aws)      (revision 20105)
    +++ src/main/java/com/amazonaws/http/HttpClientFactory.java     (thirdparty/aws)    (working copy)
    @@ -93,7 +93,7 @@
    
                            SSLSocketFactory sf = new SSLSocketFactory(
                                    SSLContext.getDefault(),
    -                               SSLSocketFactory.STRICT_HOSTNAME_VERIFIER);
    +                               SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
    
  4. 正确的解决方法是从域名存储桶处理更改为基于路径的处理。

顺便说一句,以下似乎它可能有效,但它没有。AWS 客户端专门请求STRICT验证者,不使用默认的:

SSLSocketFactory.getSystemSocketFactory().setHostnameVerifier(
    SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
于 2012-10-05T22:51:17.807 回答