带 HTTPS 的 KSOAP 2 Android
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3440062/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
KSOAP 2 Android with HTTPS
提问by rallat
I am using KSOAP2 to manage SOAP in Android but it use https for the SOAP url and I am getting this error: javax.net.ssl.SSLException: Not trusted server certificate
A normal error because the certificate is untrusted, but anyone knows how to workaround with this error?
I can not manage the certificate because is from a other company and I don't have access to change it.
我正在使用 KSOAP2 来管理 Android 中的 SOAP,但它使用 https 作为 SOAP url 并且我收到此错误:javax.net.ssl.SSLException:不可信服务器证书
一个正常错误,因为证书不受信任,但任何人都知道如何解决此错误的方法?我无法管理证书,因为它来自其他公司,我无权更改它。
Thanks
谢谢
采纳答案by zirael
I can't comment yet so i post my comments to rallat answer here. His solution works but it needs further explanations. To run ksoap2 with ssl:
我还不能发表评论,所以我在这里发表我的评论给 rallat 答案。他的解决方案有效,但需要进一步解释。使用 ssl 运行 ksoap2:
- Put
ksoap2-android-assembly-2.5.2-jar-with-dependencies.jar
in a project - Download ksoap2 sources from https://github.com/mosabua/ksoap2-android/tree/(ksoap2 repository)
- Copy
HttpTransportSE.java
,ServiceConnectionSE.java
(I also needed to copyTransport.java
,ServiceConnection.java
andHeaderProperty.java
). Delete imports from those files and make sure that they use your files (not imports fromksoap2.jar
) Use rallat answer ( I copy-pasted it):
ServiceConnectionSE.java
add this for accept untrusted certificate:private TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() { public java.security.cert.X509Certificate[] getAcceptedIssuers() { return null; } public void checkClientTrusted( java.security.cert.X509Certificate[] certs, String authType) { } public void checkServerTrusted( java.security.cert.X509Certificate[] certs, String authType) { } } };
then use this constructors to allow untrusted certificates and not verified hostnames:
public ServiceConnectionSE(String url) throws IOException { try { SSLContext sc = SSLContext.getInstance("TLS"); sc.init(null, trustAllCerts, new java.security.SecureRandom()); HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); } catch (Exception e) { e.getMessage(); } connection = (HttpsURLConnection) new URL(url).openConnection(); ((HttpsURLConnection) connection).setHostnameVerifier(new AllowAllHostnameVerifier()); }
Second contructor
public ServiceConnectionSE(Proxy proxy, String url) throws IOException { try { SSLContext sc = SSLContext.getInstance("TLS"); sc.init(null, trustAllCerts, new java.security.SecureRandom()); HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); } catch (Exception e) { e.getMessage(); } connection = (HttpsURLConnection) new URL(url).openConnection(); ((HttpsURLConnection) connection).setHostnameVerifier(new AllowAllHostnameVerifier()); connection.setUseCaches(false); connection.setDoOutput(true); connection.setDoInput(true); }
In your code just use:
HttpTransportSE aht = new HttpTransportSE(URL); aht.call(SOAP_ACTION, envelope);
- 放入
ksoap2-android-assembly-2.5.2-jar-with-dependencies.jar
一个项目 - 从https://github.com/mosabua/ksoap2-android/tree/(ksoap2存储库)下载 ksoap2 源代码
- 复制
HttpTransportSE.java
,ServiceConnectionSE.java
(我还需要复制Transport.java
,ServiceConnection.java
和HeaderProperty.java
)。从这些文件中删除导入并确保它们使用您的文件(而不是从 导入ksoap2.jar
) 使用 rallat 答案(我复制粘贴了它):
ServiceConnectionSE.java
添加此以接受不受信任的证书:private TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() { public java.security.cert.X509Certificate[] getAcceptedIssuers() { return null; } public void checkClientTrusted( java.security.cert.X509Certificate[] certs, String authType) { } public void checkServerTrusted( java.security.cert.X509Certificate[] certs, String authType) { } } };
然后使用这个构造函数来允许不受信任的证书和未经验证的主机名:
public ServiceConnectionSE(String url) throws IOException { try { SSLContext sc = SSLContext.getInstance("TLS"); sc.init(null, trustAllCerts, new java.security.SecureRandom()); HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); } catch (Exception e) { e.getMessage(); } connection = (HttpsURLConnection) new URL(url).openConnection(); ((HttpsURLConnection) connection).setHostnameVerifier(new AllowAllHostnameVerifier()); }
第二建设者
public ServiceConnectionSE(Proxy proxy, String url) throws IOException { try { SSLContext sc = SSLContext.getInstance("TLS"); sc.init(null, trustAllCerts, new java.security.SecureRandom()); HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); } catch (Exception e) { e.getMessage(); } connection = (HttpsURLConnection) new URL(url).openConnection(); ((HttpsURLConnection) connection).setHostnameVerifier(new AllowAllHostnameVerifier()); connection.setUseCaches(false); connection.setDoOutput(true); connection.setDoInput(true); }
在您的代码中只需使用:
HttpTransportSE aht = new HttpTransportSE(URL); aht.call(SOAP_ACTION, envelope);
Other things as in tutorials
教程中的其他内容
回答by Neonigma
Checking again this problem, I've discovered a more clean solution for me. No KSOAP2 files modification needed.
再次检查这个问题,我发现了一个更干净的解决方案。无需修改 KSOAP2 文件。
In your project, link the ksoap2-android-assembly-3.0.0-jar
, with no modifications.
在您的项目中,链接ksoap2-android-assembly-3.0.0-jar
,无需修改。
Next, create a file named SSLConnection.java
with this code:
接下来,创建一个SSLConnection.java
使用以下代码命名的文件:
package com.example.mypackage;
import android.util.Log;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
public class SSLConection {
private static TrustManager[] trustManagers;
public static class _FakeX509TrustManager implements javax.net.ssl.X509TrustManager {
private static final X509Certificate[] _AcceptedIssuers = new X509Certificate[]{};
public void checkClientTrusted(X509Certificate[] arg0, String arg1)
throws CertificateException {
}
public void checkServerTrusted(X509Certificate[] arg0, String arg1)
throws CertificateException {
}
public X509Certificate[] getAcceptedIssuers() {
return (_AcceptedIssuers);
}
}
public static void allowAllSSL() {
javax.net.ssl.HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
});
javax.net.ssl.SSLContext context;
if (trustManagers == null) {
trustManagers = new TrustManager[]{new _FakeX509TrustManager()};
}
try {
context = javax.net.ssl.SSLContext.getInstance("TLS");
context.init(null, trustManagers, new SecureRandom());
javax.net.ssl.HttpsURLConnection.setDefaultSSLSocketFactory(context.getSocketFactory());
} catch (NoSuchAlgorithmException e) {
Log.e("allowAllSSL", e.toString());
} catch (KeyManagementException e) {
Log.e("allowAllSSL", e.toString());
}
}
}
And just call to SSLConection.allowAllSSL();
before calling a server method via KSOAP2. It's all, works for me. All SSL certificates are accepted and I can use KSOAP2 with https protocol.
只需SSLConection.allowAllSSL();
在通过 KSOAP2 调用服务器方法之前调用 。这一切,对我有用。接受所有 SSL 证书,我可以将 KSOAP2 与 https 协议一起使用。
回答by jowett
Create a new class FakeX509TrustManager to handle the certificate problem,
创建一个新类 FakeX509TrustManager 来处理证书问题,
FakeX509TrustManager.allowAllSSL();
HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
The new created class is as the following:
新创建的类如下:
public class FakeX509TrustManager implements X509TrustManager {
private static TrustManager[] trustManagers;
private static final X509Certificate[] _AcceptedIssuers = new
X509Certificate[] {};
@Override
public void checkClientTrusted(X509Certificate[] chain, String
authType) throws CertificateException {
}
@Override
public void checkServerTrusted(X509Certificate[] chain, String
authType) throws CertificateException {
}
public boolean isClientTrusted(X509Certificate[] chain) {
return true;
}
public boolean isServerTrusted(X509Certificate[] chain) {
return true;
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return _AcceptedIssuers;
}
public static void allowAllSSL() {
HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier()
{
@Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
});
SSLContext context = null;
if (trustManagers == null) {
trustManagers = new TrustManager[] { new FakeX509TrustManager() };
}
try {
context = SSLContext.getInstance("TLS");
context.init(null, trustManagers, new SecureRandom());
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (KeyManagementException e) {
e.printStackTrace();
}
HttpsURLConnection.setDefaultSSLSocketFactory(context.getSocketFactory());
}
}
回答by rallat
I find the answer by myself
我自己找答案
on ServiceConnectionSE.java add this for accept untrusted certificate:
private TrustManager[] trustAllCerts = new TrustManager[]{ new X509TrustManager() { public java.security.cert.X509Certificate[] getAcceptedIssuers() { return null; } public void checkClientTrusted( java.security.cert.X509Certificate[] certs, String authType) { } public void checkServerTrusted( java.security.cert.X509Certificate[] certs, String authType) { } } };
then in the constructor add this to allow untrusted certificates and not verified hostnames:
try { SSLContext sc = SSLContext.getInstance("TLS"); sc.init(null, trustAllCerts, new java.security.SecureRandom()); HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); } catch (Exception e) { e.getMessage(); } connection = (HttpsURLConnection) new URL(url).openConnection(); ((HttpsURLConnection) connection).setHostnameVerifier(new AllowAllHostnameVerifier());
在 ServiceConnectionSE.java 上添加此以接受不受信任的证书:
private TrustManager[] trustAllCerts = new TrustManager[]{ new X509TrustManager() { public java.security.cert.X509Certificate[] getAcceptedIssuers() { return null; } public void checkClientTrusted( java.security.cert.X509Certificate[] certs, String authType) { } public void checkServerTrusted( java.security.cert.X509Certificate[] certs, String authType) { } } };
然后在构造函数中添加它以允许不受信任的证书和未验证的主机名:
try { SSLContext sc = SSLContext.getInstance("TLS"); sc.init(null, trustAllCerts, new java.security.SecureRandom()); HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); } catch (Exception e) { e.getMessage(); } connection = (HttpsURLConnection) new URL(url).openConnection(); ((HttpsURLConnection) connection).setHostnameVerifier(new AllowAllHostnameVerifier());