简体   繁体   English

使用 Java API 的 S3/AWS 的 SSL 问题:“证书中的主机名不匹配”

[英]SSL problems with S3/AWS using the Java API: “hostname in certificate didn't match”

Amazon "upgraded" the SSL security in its AWS Java SDK in the 1.3.21 version.亚马逊在 1.3.21 版本中“升级”了其 AWS Java SDK 中的 SSL 安全性。 This broke access any S3 buckets that have periods in their name when using Amazon's AWS Java API.在使用 Amazon 的 AWS Java API 时,这会中断对名称中包含句点的任何 S3 存储桶的访问。 I'm using version 1.3.21.1 which is current up to Oct/5/2012.我使用的版本是 1.3.21.1,最新版本是 2012 年 10 月 5 日。 I've provided some solutions in my answer below but I'm looking for additional work arounds to this issue.我在下面的回答中提供了一些解决方案,但我正在寻找解决此问题的其他方法。

If you are getting this error, you will see something like the following message in your exceptions/logs.如果您收到此错误,您将在异常/日志中看到类似于以下消息的内容。 In this example, the bucket name is foo.example.com .在此示例中,存储桶名称为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)

You can see documentation of this problem on the AWS S3 discussion forum:您可以在 AWS S3 论坛上查看此问题的文档:

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

Amazon's response to the problem is the following.亚马逊对此问题的回应如下。

We should be able to fix this by using the older path style method of bucket addressing (instead of the newer virtual host style addressing) for buckets with this naming pattern.我们应该能够通过对具有此命名模式的存储桶使用旧的路径样式的存储桶寻址方法(而不是较新的虚拟主机样式寻址)来解决此问题。 We'll get started on the fix and ensure that our internal integration tests have test cases for buckets names containing periods.我们将开始修复并确保我们的内部集成测试具有包含句点的存储桶名称的测试用例。

Any workaround or other solutions?任何解决方法或其他解决方案? Thanks for any feedback.感谢您的任何反馈。

Original: October 2012原文:2012 年 10 月

Turns out that Amazon "upgraded" the SSL security on S3 in late September 2012. This broke access any S3 buckets that have periods in their name when using Amazon's AWS Java API.事实证明,亚马逊在 2012 年 9 月下旬“升级”了 S3 上的 SSL 安全性。这会在使用亚马逊的 AWS Java API 时中断对名称中包含句点的任何 S3 存储桶的访问。

This is inaccurate.这是不准确的。 S3's SSL wildcard matching has been the same as when S3 launched back in 2006. What's more likely is that the AWS Java SDK team enabled stricter validation of SSL certificates (good), but ended up breaking bucket names that have been running afoul of S3's SSL cert (bad). S3 的 SSL 通配符匹配与 S3 在 2006 年推出时相同。更有可能的是,AWS Java SDK 团队启用了更严格的 SSL 证书验证(很好),但最终破坏了与 S3 的 SSL 冲突的存储桶名称证书(坏)。

The right answer is that you need to use path-style addressing instead of DNS-style addressing.正确的答案是您需要使用路径式寻址而不是DNS 式寻址。 That is the only secure way of working around the issue with the wildcard matching on the SSL certificate.这是解决 SSL 证书上的通配符匹配问题的唯一安全方法。 Disabling the verification opens you up to Man-In-The-Middle attacks.禁用验证会使您面临中间人攻击。

What I don't presently know is if the Java SDK provides this as a configurable option.我目前不知道的是 Java SDK 是否将其作为可配置选项提供。 If so, that's your answer.如果是这样,这就是你的答案。 Otherwise, it sounds like the Java SDK team said "we'll add this feature, and then add integration tests to make sure it all works."否则,听起来 Java SDK 团队说“我们将添加此功能,然后添加集成测试以确保一切正常。”

Update: October 2020更新:2020 年 10 月

AWS has announced that path-style addressing is deprecated will be going away in the near-future. AWS 宣布不推荐使用的路径式寻址将在不久的将来消失。 AWS' advice is to use DNS-compatible bucket names, which means no periods (among a few other things). AWS 的建议是使用与 DNS 兼容的存储桶名称,这意味着没有句点(以及其他一些内容)。 Certain newer features of S3 require DNS-compatible bucket names (eg, accelerated transfer). S3 的某些较新功能需要与DNS 兼容的存储桶名称(例如,加速传输)。

If you require a bucket name which contains periods (which will also be disallowed for new buckets in the near future), my best advice is to put a CloudFront distribution in front of it if you want to hit it over HTTPS.如果您需要一个包含句点的存储桶名称(在不久的将来,新存储桶也将不允许使用),我最好的建议是,如果您想通过 HTTPS 访问它,请将 CloudFront 分配放在它前面。

Amazon released version 1.3.22 which resolves this issue.亚马逊发布了 1.3.22 版本,解决了这个问题。 I've verified that our code now works.我已经验证我们的代码现在可以工作了。 To quote from their release notes:引用他们的发行说明:

Buckets whose name contains periods can now be correctly addressed again over HTTPS.名称包含句点的存储桶现在可以通过 HTTPS 再次正确寻址。

There are a couple of solutions that I can see, aside from waiting till Amazon releases a new API.除了等待亚马逊发布新 API 之外,我还可以看到几种解决方案。

  1. Obviously you could roll back to 1.3.20 version of the AWS Java SDK.显然,您可以回滚到 AWS Java SDK 的 1.3.20 版本。 Unfortunately I needed some of the features in 1.3.21.不幸的是,我需要 1.3.21 中的一些功能。

  2. You can replace the org.apache.http.conn.ssl.StrictHostnameVerifier in the classpath.您可以替换类路径中的org.apache.http.conn.ssl.StrictHostnameVerifier This is a hack however which will remove all SSL checking for Apache http connections I think.但是,这是一个hack ,我认为它将删除对 Apache http 连接的所有 SSL 检查。 Here's the code that worked for me: http://pastebin.com/bvFELdJE这是对我有用的代码: http : //pastebin.com/bvFELdJE

  3. I ended up downloading and building my own package from the AWS source jar.我最终从 AWS 源 jar 下载并构建了我自己的包。 I applied the following approximate patch to the HttpClientFactory source.我将以下近似补丁应用于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. The right fix is to change from domain-name bucket handling to path based handling.正确的解决方法是从域名桶处理更改为基于路径的处理。

Btw, the following seems like it might work but it does not .顺便说一句,以下内容似乎可能有效,但无效 The AWS client specifically requests the STRICT verifier and does not use the default one: AWS 客户端专门请求STRICT验证器,并且不使用默认验证器:

SSLSocketFactory.getSystemSocketFactory().setHostnameVerifier(
    SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用HTTPS Confusion的Java HTTP帖子 - javax.net.ssl.SSLException:证书中的主机名不匹配 - Java HTTP post using HTTPS Confusion - javax.net.ssl.SSLException: hostname in certificate didn't match Java SSLException:证书中的主机名不匹配 - Java SSLException: hostname in certificate didn't match Litle API jar的SSL问题-证书中的主机名不匹配:&lt;208.70.177.61&gt;!= <prelive.litle.com> - SSL Issue with Litle API jar - hostname in certificate didn't match: <208.70.177.61> != <prelive.litle.com> RestEasy的客户端实现导致javax.net.ssl.SSLException:证书中的主机名不匹配 - RestEasy's Client implementation causes javax.net.ssl.SSLException: hostname in certificate didn't match javax.net.ssl.SSLException:证书中的主机名不匹配 - javax.net.ssl.SSLException: hostname in certificate didn't match 证书中的主机名不匹配? - Hostname in certificate didn't match? 证书中的主机名不匹配 - Hostname in certificate didn't match Java SSLException:证书中的主机名在Android应用程序中不匹配 - Java SSLException: hostname in certificate didn't match in android application 证书中的主机名与通配符证书不匹配 - Hostname in certificate didn't match on wildcard cert SSLHandshakeException:证书中的主机名不匹配 - SSLHandshakeException: hostname in certificate didn't match
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM