Я разрабатываю приложение на Android, которое использует веб-сервис REST.Веб-сервис находится в HTTPS.Я не могу предоставить информацию о веб-сервисе, так как это конфиденциально.Я выполнил действия, указанные в ссылке ниже:
http://blog.antoine.li/index.php/2010/10/android-trusting-ssl-certificates/
Приложение до сих пор работало нормально и могло загружать контент веб-службы.Внезапно в последнюю неделю он не смог подключиться и выдает «javax.net.ssl.SSLException: сертификат недоверенного сервера».Я выполнил следующие шаги, чтобы настроить это:
Шаг 1: Я использовал корневой сертификат, предоставленный GeoTrust, в своем приложении для обеспечения безопасной связи.Собранный корневой сертификат «GeoTrust_Global_CA.cer» с трастового сайта Geo: http://www.geotrust.com/resources/root-certificates/index.html
Это кодированный в Base64 формат X.509.
Шаг 2: Скачал провайдера BouncyCastle и с помощью этого созданного хранилища ключей.Я запустил следующие команды, используя java 6 keytool из командной строки, чтобы создать хранилище ключей:
keytool -importcert -v -trustcacerts -file "G: \ workspace \ TestHttps \ GeoTrustglobal.cer" -alias IntermediateCA -keystore "G: \ workspace \ TestHttps \ res \ raw \ mykeystore.bks "-provider org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath" G: \ workspace \ TestHttps \ SigningProcess \ bcprov-jdk16-146.jar "-storestype BKS -reprepmysecret
После успешной работы он создает myKeyStore.bks, и я скопировал его в папку / res / raw моего приложения.
Затем проверил это хранилище ключей, выполнив следующую команду:
keytool -importcert -v -trustcacerts -file "G: \ workspace \ TestHttps \ GeoTrustglobal.cer" -alias IntermediateCA -keystore "G: \ workspace \ TestHttps \ res \ raw \ mykeystore.bks "-provider org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath" G: \ workspace \ TestHttps \ SigningProcess \ bcprov-jdk16-146.jar "-storetype BKS -storepass mysecret
Возвращено 1 результат с промежуточным сертификатом следующим образом:
IntermediateCA, 22.10.2010 ,rustCertEntry, отпечаток большого пальца (MD5): 98: 0F: C3: F8: 39: F7: D8: 05: 07: 02: 0D: E3: 14: 5B: 29: 43
Шаг 3:
Теперь я написал следующий код, который расширен от DefaultHttpClient
public class MyHttpClient extends DefaultHttpClient {
final Context context;
public MyHttpClient(Context context) {
this.context = context;
}
@Override
protected ClientConnectionManager createClientConnectionManager() {
SchemeRegistry registry = new SchemeRegistry();
registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
// Register for port 443 our SSLSocketFactory with our keystore
// to the ConnectionManager
registry.register(new Scheme("https", newSslSocketFactory(), 443));
return new SingleClientConnManager(getParams(), registry);
}
private SSLSocketFactory newSslSocketFactory() {
try {
// Get an instance of the Bouncy Castle KeyStore format
KeyStore trusted = KeyStore.getInstance("BKS");
// Get the raw resource, which contains the keystore with
// your trusted certificates (root and any intermediate certs)
InputStream in = context.getResources().openRawResource(R.raw.mykeystore);
try {
// Initialize the keystore with the provided trusted certificates
// Also provide the password of the keystore
trusted.load(in, "mysecret".toCharArray());
} finally {
in.close();
}
// Pass the keystore to the SSLSocketFactory. The factory is responsible
// for the verification of the server certificate.
SSLSocketFactory sf = new SSLSocketFactory(trusted);
// Hostname verification from certificate
// http://hc.apache.org/httpcomponents-client-ga/tutorial/html/connmgmt.html#d4e506
sf.setHostnameVerifier(SSLSocketFactory.STRICT_HOSTNAME_VERIFIER);
return sf;
} catch (Exception e) {
throw new AssertionError(e);
}
}
}
Затем я вызвал DefaultHttpClient, используя следующий код:
package com.test.https;
import java.io.IOException;
import java.net.UnknownHostException;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.ParseException;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import android.app.Activity;
import android.os.Bundle;
public class TestHttps extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
try {
startConnect();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void startConnect() throws UnknownHostException{
DefaultHttpClient client = new MyHttpClient(getApplicationContext());
HttpGet get = new HttpGet("https://ssltest15.bbtest.net/");
// Execute the GET call and obtain the response
HttpResponse getResponse = null;
try {
getResponse = client.execute(get);
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch(UnknownHostException uhe){
uhe.printStackTrace();
throw new UnknownHostException();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String response = null;
if(getResponse != null){
HttpEntity responseEntity = getResponse.getEntity();
try {
response = EntityUtils.toString(responseEntity);
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
Когда я выполнил этот код, он выдает следующее исключение:
java.security.cert.CertPathValidatorException: TrustAnchor for CertPath не найден.
javax.net.ssl.SSLException: недоверенный сертификат сервера
Поэтому я попытался использовать то же приложение для подключения к различным другим веб-службам, включая ту, которая предоставляется geotrust (https://ssltest15.bbtest.net/).Все бросают одно и то же исключение.Я полагаю, что
Веб-сервер, который предоставляет веб-службу REST, может иметь некоторые изменения на их стороне, что вызывает эту проблему
Срок действия сертификата Geo Trust, который я использую, истек
Шаги, которые я выполнил, имеют некоторые проблемы
То же приложение, что и вышекод работал нормально до 1 недели, теперь внезапно происходит сбой, значит, произошли некоторые изменения на стороне сервера, вызвавшие эту проблему.Я неясно о точной проблеме.
Если кто-нибудь может помочь мне понять проблему, мы будем очень признательны.Заранее спасибо.