Java 具有Android和自签名服务器证书的HTTPS GET(SSL)

Java 具有Android和自签名服务器证书的HTTPS GET(SSL),java,android,ssl,Java,Android,Ssl,我已经阅读了关于如何在Android上通过HTTPS从使用自签名证书的服务器检索内容的各种帖子。然而,它们似乎都不起作用——它们都无法移除 javax.net.ssl.SSLException:不受信任的服务器证书消息 这不是修改服务器以获得受信任证书的选项,也不是使服务器证书与服务器的IP地址匹配的选项 请注意,服务器将没有DNS名称,它将只有一个IP地址。GET请求如下所示: https://username:password@anyIPAddress/blabla/index.php?p

我已经阅读了关于如何在Android上通过
HTTPS
从使用自签名证书的服务器检索内容的各种帖子。然而,它们似乎都不起作用——它们都无法移除

javax.net.ssl.SSLException:不受信任的服务器证书消息

这不是修改服务器以获得受信任证书的选项,也不是使服务器证书与服务器的IP地址匹配的选项

请注意,服务器将没有DNS名称,它将只有一个IP地址。GET请求如下所示:

 https://username:password@anyIPAddress/blabla/index.php?param=1&param2=3
我完全知道,此解决方案容易受到中间人攻击等

因此,解决方案必须忽略证书中缺乏信任,并忽略主机名不匹配

有人知道使用Java for Android的代码吗


有很多尝试来解释这一点,也有很多代码片段,但它们似乎不起作用,而且据我所知,没有人提供一块代码来解决这个问题。如果有人真的解决了这个问题,或者Android只是阻止了不受信任的证书,那就很有意思了。

如果您使用的是HttpsURLConnection,那么在
connect()之前尝试调用它上的
setHostnameVerifier
,并将其传递给主机名验证器,该验证器将不考虑准确性而直接接受。

如果您有权访问设备,则可以将证书添加到密钥库

另一方面,你可以使用这种方法,但我认为它有点难看


资源:

关于同一主题:


我制作了一个使用自签名或信任所有证书的应用程序。源代码是免费的,可以使用:P


只需使用HttpManager并使用trustall-one创建SSL工厂。找到示例代码。

您可以安静安全地执行此操作:

如果您要求我,请以安全的方式执行此操作

找到了一个很好的教程,其实并不难实现

另外,Maciek推荐的教程非常好


我测试了它,它在我的应用程序中运行没有问题。

正如您正确指出的,有两个问题:a)证书不可信,b)证书上的名称与主机名不匹配

警告:对于得到这个答案的任何人来说,这是一个肮脏、可怕的黑客行为,你不能将它用于任何重要的事情。没有身份验证的SSL/TLS比根本没有加密更糟糕-读取和修改“加密”数据对于攻击者来说是微不足道的,而您甚至不知道它正在发生

还和我在一起吗?我怕是这样

a) 通过创建自定义SSLContext来解决此问题,TrustManager接受任何内容:

SSLContext ctx = SSLContext.getInstance("TLS");
ctx.init(null, new TrustManager[] {
  new X509TrustManager() {
    public void checkClientTrusted(X509Certificate[] chain, String authType) {}
    public void checkServerTrusted(X509Certificate[] chain, String authType) {}
    public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[]{}; }
  }
}, null);
HttpsURLConnection.setDefaultSSLSocketFactory(ctx.getSocketFactory());
和b)通过创建HostnameVerifier,即使证书与主机名不匹配,也允许连接继续:

HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
  public boolean verify(String hostname, SSLSession session) {
    return true;
  }
});

这两种情况都必须发生在代码的开头,然后再开始处理HttpsURLConnections等等。这在Android和常规JRE中都有效。享受。

我在4个月前制作了一个使用自签名证书的应用程序,下面是代码,我希望它能有所帮助:

它对我有用,但无可否认是用Java编写的。您确定在对连接执行任何I/O之前调用了它吗?我尝试了许多不同的代码段,它们都替换了主机名验证器,并忽略了不同类型的SSL证书,但无论复制哪个代码段,证书错误消息都会不断出现。对我来说,发布特定的源代码是没有意义的,因为我已经尝试了几种不同的解决方案——我希望看到的是在Android上工作的东西。以前一定有人解决过这个问题,应该能够复制和粘贴一些源代码……如果你尝试在非android设备上使用Java连接到同一台服务器会发生什么情况?Yuliy,你的问题只有在我有一段代码失败,并且我试图修复那段代码时才有意义。但是我尝试了许多不同的代码,来自stackoverflow.com和其他地方。其中一些可能在Android之外工作,一些可能不工作。那对我没有帮助。我们的目标是找到一个完整的Android代码片段,这是已知的工作。Lars,我要求尝试并确定它在Android上是否是一个危险的事实。这就是尝试从桌面java客户端执行SSL连接所要做的。我已经尝试了您链接到的两个源代码片段,但都报告服务器证书不可信,似乎根本不起作用。我还尝试了“HTTPS连接android”线程中的一些代码,结果相同。困扰我的是,所有试图提供帮助的人都没有提供一个有效的代码段,如果我将他们提供的代码段组合在一起,它就不起作用了。将证书添加到密钥库是一个解决方法,但这是一个繁琐的过程,因为这需要客户机了解服务器配置,这是一个不必要的假设。在我看来,如果不想使用密钥库,最好的解决方法是重写自己的
SSLSocketFactory
。本教程详细解释了如何做到这一点:这应该是一个普通框架中的一行程序,我想知道为什么没有人可以粘贴代码段。就像@Lars D所说的,其他解决方案不起作用,但这一个可以,非常感谢!我太高兴了,我可以哭了。这段代码是经过多次搜索后第一个有效的解决方案。感谢x1000开放源代码!似乎无法使这项工作成功。我将HttpManager中的SSLSocketFactory更改为“TrustAllSSLSocketFactory”,但我一直得到“java.security.cert.certpathvalidatorexception:找不到证书路径的信任锚点。返回一个无效的会话