我正在開發一個使用REST Web服務的Android應用程序。該Web服務位於HTTPS中。我無法提供Web服務的詳細信息,因爲它是保密的。我也跟着在下面的鏈接中提到的步驟:從Android連接到REST web服務拋出javax.net.ssl.SSLException:不可信的服務器證書
http://blog.antoine.li/index.php/2010/10/android-trusting-ssl-certificates/
應用程序工作正常,到目前爲止,並能下載網站服務的內容。突然最後一週,它無法連接並拋出「javax.net.ssl.SSLException:不受信任的服務器證書」。我按照下面提到的步驟設置:
第1步:我使用GeoTrust提供的根證書在我的應用程序中啓用安全通信。如此從地理信任站點收集根證書「GeoTrust_Global_CA.cer」: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「-storetype BKS -storepass mysecret
成功後,它創建myKeyStore.bks,並將其複製到我的應用程序的/ res/raw文件夾中。
密鑰工具-importcert -v -trustcacerts -file:
然後通過運行下面的命令驗證這個密鑰存儲 「G:\工作空間\ TestHttps \ GeoTrustglobal.cer」 -alias IntermediateCA -keystore「G:\工作區\ 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結果與中間證書如下:
中級CA,22.10.2010,trustedCertEntry,Th umbprint(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:找不到CertPath的TrustAnchor。
javax.net.ssl。異常SSLException:不受信任的服務器證書
所以,我想同樣的應用程序連接到各種其他網絡服務,包括一個由GeoTrust的(https://ssltest15.bbtest.net/)提供。所有拋出相同的例外。我對這個問題的猜測是,
正在提供REST Web服務的Web服務器,可能就在自己身邊的一些變化,導致此問題
我使用的地理信託cerificate已過期
步驟我跟着有一些問題
與上面的代碼相同的應用程序工作正常之前我們1 ek,現在突然失敗意味着,服務器端發生了一些變化,導致此問題。我不清楚確切的問題。
如果有人能幫助我理解這個問題,非常感謝。提前致謝。
嗨。你有沒有辦法解決?我也面臨同樣的問題 – 2011-07-17 05:04:31
看起來在服務器端存在一些問題。我們正在努力。 – Vignesh 2011-07-20 18:25:54