Java Android上的HTTPS身份验证
我有一些Android的HTTP认证代码。但它不适用于https身份验证。如何在https授权下重新考虑代码 HTTP验证代码如下:Java Android上的HTTPS身份验证,java,android,https,authorization,Java,Android,Https,Authorization,我有一些Android的HTTP认证代码。但它不适用于https身份验证。如何在https授权下重新考虑代码 HTTP验证代码如下: HttpUriRequest request = new HttpGet(HOST); String credentials = login + ":" + mPassword; authString = "Basic " + Base64.encodeToString(credentials.getBytes(), Base64.NO_WRAP); Shared
HttpUriRequest request = new HttpGet(HOST);
String credentials = login + ":" + mPassword;
authString = "Basic " + Base64.encodeToString(credentials.getBytes(), Base64.NO_WRAP);
SharedPreferences.Editor editor = prefs.edit();
editor.putString("auth", authString);
editor.apply();
request.addHeader("Authorization", authString);
HttpClient httpClient = new DefaultHttpClient();
int result = 0;
try {
HttpResponse response = httpClient.execute(request);
result = response.getStatusLine().getStatusCode();
System.out.println(response.getStatusLine());
} catch (Exception e) {
result = -1;
}
return result;
然而,HttpClient的默认行为适用于大多数用途
您可能需要配置一些方面。最
自定义SSL的常见要求包括:
Protocol myhttps = new Protocol("https", new MySSLSocketFactory(), 443);
Protocol.registerProtocol("https",
new Protocol("https", new MySSLSocketFactory(), 443));
HttpClient httpclient = new HttpClient();
GetMethod httpget = new GetMethod("https://www.whatever.com/");
try {
httpclient.executeMethod(httpget);
System.out.println(httpget.getStatusLine());
} finally {
httpget.releaseConnection();
}
mysslssocketfactory
是一个自定义套接字工厂,它实现了org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory
接口
您可以参考此链接:
然而,HttpClient的默认行为适用于大多数用途
您可能需要配置一些方面。最
自定义SSL的常见要求包括:
Protocol myhttps = new Protocol("https", new MySSLSocketFactory(), 443);
Protocol.registerProtocol("https",
new Protocol("https", new MySSLSocketFactory(), 443));
HttpClient httpclient = new HttpClient();
GetMethod httpget = new GetMethod("https://www.whatever.com/");
try {
httpclient.executeMethod(httpget);
System.out.println(httpget.getStatusLine());
} finally {
httpget.releaseConnection();
}
mysslssocketfactory
是一个自定义套接字工厂,它实现了org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory
接口
您可以引用此链接:我使用自定义ssl套接字工厂并使用参数创建HTTP客户端解决了此问题 CustomSSLSocketFactory:
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import org.apache.http.conn.ssl.SSLSocketFactory;
public class CustomSSLSocketFactory extends SSLSocketFactory{
SSLContext sslContext = SSLContext.getInstance("TLS");
/**
* Generate Certificate for ssl connection
* @param truststore
* @throws NoSuchAlgorithmException
* @throws KeyManagementException
* @throws KeyStoreException
* @throws UnrecoverableKeyException
*/
public CustomSSLSocketFactory(KeyStore truststore)
throws NoSuchAlgorithmException, KeyManagementException,
KeyStoreException, UnrecoverableKeyException {
super(truststore);
TrustManager tm = new X509TrustManager(){
@Override
public void checkClientTrusted(X509Certificate[] arg0, String arg1)
throws CertificateException {
}
@Override
public void checkServerTrusted(X509Certificate[] chain,
String authType) throws CertificateException {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
};
sslContext.init(null, new TrustManager[] {tm}, null);
}
@Override
public Socket createSocket(Socket socket, String host, int port,
boolean autoClose) throws IOException, UnknownHostException {
return sslContext.getSocketFactory().createSocket(socket, host, port,
autoClose);
}
@Override
public Socket createSocket() throws IOException {
return sslContext.getSocketFactory().createSocket();
}
}
用于创建HTTP客户端的End util:
import java.security.KeyStore;
import org.apache.http.client.HttpClient;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpParams;
public class HTTPUtils {
/**
* HttpClient
* @param isHTTPS
* @return
*/
public static HttpClient getNewHttpClient(boolean isHTTPS) {
try {
if(!isHTTPS){
return getNewHttpClient();
}
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
trustStore.load(null, null);
SSLSocketFactory sf = new CustomSSLSocketFactory(trustStore);
sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
HttpParams params = new BasicHttpParams();
SchemeRegistry registry = new SchemeRegistry();
registry.register(new Scheme("https", sf, 443));
ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, registry);
return new DefaultHttpClient(ccm, params);
} catch (Exception e) {
return null;
}
}
/**
* HttpClient for http request
* @return
*/
private static HttpClient getNewHttpClient(){
HttpParams params = new BasicHttpParams();
return new DefaultHttpClient(params);
}
}
例如:
String credentials = login + ":" + mPassword;
authString = "Basic " + Base64.encodeToString(credentials.getBytes(), Base64.NO_WRAP);
HttpClient httpclient = HTTPUtils.getNewHttpClient(HOST.startsWith(HTTPS_STRING));
URI newURI = URI.create(HOST);
HttpGet httpGet = new HttpGet(newURI);
httpGet.setHeader("Authorization", authString);
try {
HttpResponse response = httpclient.execute(httpGet);
int code = response.getStatusLine().getStatusCode();
return code;
...
我解决了这个问题,使用自定义ssl套接字工厂并使用params创建HTTP客户端 CustomSSLSocketFactory:
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import org.apache.http.conn.ssl.SSLSocketFactory;
public class CustomSSLSocketFactory extends SSLSocketFactory{
SSLContext sslContext = SSLContext.getInstance("TLS");
/**
* Generate Certificate for ssl connection
* @param truststore
* @throws NoSuchAlgorithmException
* @throws KeyManagementException
* @throws KeyStoreException
* @throws UnrecoverableKeyException
*/
public CustomSSLSocketFactory(KeyStore truststore)
throws NoSuchAlgorithmException, KeyManagementException,
KeyStoreException, UnrecoverableKeyException {
super(truststore);
TrustManager tm = new X509TrustManager(){
@Override
public void checkClientTrusted(X509Certificate[] arg0, String arg1)
throws CertificateException {
}
@Override
public void checkServerTrusted(X509Certificate[] chain,
String authType) throws CertificateException {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
};
sslContext.init(null, new TrustManager[] {tm}, null);
}
@Override
public Socket createSocket(Socket socket, String host, int port,
boolean autoClose) throws IOException, UnknownHostException {
return sslContext.getSocketFactory().createSocket(socket, host, port,
autoClose);
}
@Override
public Socket createSocket() throws IOException {
return sslContext.getSocketFactory().createSocket();
}
}
用于创建HTTP客户端的End util:
import java.security.KeyStore;
import org.apache.http.client.HttpClient;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpParams;
public class HTTPUtils {
/**
* HttpClient
* @param isHTTPS
* @return
*/
public static HttpClient getNewHttpClient(boolean isHTTPS) {
try {
if(!isHTTPS){
return getNewHttpClient();
}
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
trustStore.load(null, null);
SSLSocketFactory sf = new CustomSSLSocketFactory(trustStore);
sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
HttpParams params = new BasicHttpParams();
SchemeRegistry registry = new SchemeRegistry();
registry.register(new Scheme("https", sf, 443));
ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, registry);
return new DefaultHttpClient(ccm, params);
} catch (Exception e) {
return null;
}
}
/**
* HttpClient for http request
* @return
*/
private static HttpClient getNewHttpClient(){
HttpParams params = new BasicHttpParams();
return new DefaultHttpClient(params);
}
}
例如:
String credentials = login + ":" + mPassword;
authString = "Basic " + Base64.encodeToString(credentials.getBytes(), Base64.NO_WRAP);
HttpClient httpclient = HTTPUtils.getNewHttpClient(HOST.startsWith(HTTPS_STRING));
URI newURI = URI.create(HOST);
HttpGet httpGet = new HttpGet(newURI);
httpGet.setHeader("Authorization", authString);
try {
HttpResponse response = httpclient.execute(httpGet);
int code = response.getStatusLine().getStatusCode();
return code;
...
“不起作用”永远都不是一个足够好的错误描述。请扩展它,例如使用错误消息或堆栈跟踪。它在以下行冻结:HttpResponse response=httpClient.execute(request);“不起作用”永远都不是一个足够好的错误描述。请扩展它,例如使用错误消息或堆栈跟踪。它在以下行冻结:HttpResponse response=httpClient.execute(request);什么是我的袜子工厂?@OkadzakiTomoe。。请检查,我已经更新了答案,我不明白你的答案。什么是协议对象?@OkadzakiTomoe抱歉,您可能需要将apache http网络库添加到您的项目中。@OkadzakiTomoe。。您作为答案发布的链接实际上是在ANDROID上下文中执行建议的操作(创建自定义ssl套接字)。不管怎样,很高兴你解决了。我的袜子工厂是什么?@OkadzakiTomoe。。请检查,我已经更新了答案,我不明白你的答案。什么是协议对象?@OkadzakiTomoe抱歉,您可能需要将apache http网络库添加到您的项目中。@OkadzakiTomoe。。您作为答案发布的链接实际上是在ANDROID上下文中执行建议的操作(创建自定义ssl套接字)。无论如何,很高兴你解决了这个问题。不建议将链接作为答案发布,因为如果链接关闭/失效,这些答案将过时。我建议你以详细的形式补充你是如何解决的。因此,任何访问此页面的用户都只能获取此页面中的所有内容。另外,你也会因为写了好的答案而获得选票。不建议将链接作为答案发布,因为如果链接失效,这些答案就会过时。我建议你以详细的形式补充你是如何解决的。因此,任何访问此页面的用户都只能获取此页面中的所有内容。另外,你也会因为写了好的答案而获得选票。