我正在尝试将自签名SSL证书传递给我的网络服务。作为测试,我将我的客户端指向Google。
但是我收到以下错误:
startHandshake时捕获异常: javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException:信任锚 未找到证书路径
然后
使用无效密码套件返回无效会话 SSL_NULL_WITH_NULL_NULL
完整的logcat如下:
08-07 20:05:09.635 25029-25029/com.james.restfultest E/Trace﹕ error opening trace file: No such file or directory (2)
08-07 20:05:09.975 25029-25029/com.james.restfultest I/Adreno200-EGL﹕ <qeglDrvAPI_eglInitialize:299>: EGL 1.4 QUALCOMM build: AU_LINUX_ANDROID_JB_REL_RB1.04.01.01.06.043_msm8660_surf_JB_REL_RB1.2_CL2428086_release_AU (CL2428086)
Build Date: 11/15/12 Thu
Local Branch:
Remote Branch: m/jb_rel_rb1.2
Local Patches: NONE
Reconstruct Branch: AU_LINUX_ANDROID_JB_REL_RB1.04.01.01.06.043 + e534df6 + 951c251 + 07bf631 + 6aa3ec7 + e04e486 + 9f5646a + 855d11b + NOTHING
08-07 20:05:10.015 25029-25029/com.james.restfultest D/memalloc﹕ ion: Mapped buffer base:0x54242000 size:2088960 offset:0 fd:61
08-07 20:05:10.015 25029-25029/com.james.restfultest D/memalloc﹕ ion: Mapped buffer base:0x4002a000 size:4096 offset:0 fd:63
08-07 20:05:10.165 25029-25029/com.james.restfultest D/memalloc﹕ ion: Mapped buffer base:0x549c4000 size:2088960 offset:0 fd:66
08-07 20:05:10.165 25029-25029/com.james.restfultest D/memalloc﹕ ion: Mapped buffer base:0x4002c000 size:4096 offset:0 fd:68
08-07 20:05:10.556 25029-25029/com.james.restfultest D/memalloc﹕ ion: Mapped buffer base:0x54cc2000 size:2088960 offset:0 fd:70
08-07 20:05:10.556 25029-25029/com.james.restfultest D/memalloc﹕ ion: Mapped buffer base:0x40033000 size:4096 offset:0 fd:72
08-07 20:05:15.050 25029-25119/com.james.restfultest I/global﹕ call createSocket() return a new socket.
08-07 20:05:15.180 25029-25119/com.james.restfultest W/System.err﹕ Catch exception while startHandshake: javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
08-07 20:05:15.180 25029-25119/com.james.restfultest W/System.err﹕ return an invalid session with invalid cipher suite of SSL_NULL_WITH_NULL_NULL
08-07 20:05:15.230 25029-25119/com.james.restfultest W/dalvikvm﹕ threadid=11: thread exiting with uncaught exception (group=0x41f31390)
08-07 20:05:15.240 25029-25119/com.james.restfultest E/AndroidRuntime﹕ FATAL EXCEPTION: AsyncTask #1
java.lang.RuntimeException: An error occured while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:299)
at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
at java.util.concurrent.FutureTask.run(FutureTask.java:137)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
at java.lang.Thread.run(Thread.java:864)
Caused by: java.lang.StringIndexOutOfBoundsException: length=0; regionStart=7; regionLength=-7
at java.lang.String.startEndAndLength(String.java:593)
at java.lang.String.substring(String.java:1474)
at com.james.restfultest.MyAsyncTask.postData(Main.java:197)
at com.james.restfultest.MyAsyncTask.doInBackground(Main.java:163)
at com.james.restfultest.MyAsyncTask.doInBackground(Main.java:149)
at android.os.AsyncTask$2.call(AsyncTask.java:287)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
at java.util.concurrent.FutureTask.run(FutureTask.java:137)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
at java.lang.Thread.run(Thread.java:864)
08-07 20:05:15.701 25029-25029/com.james.restfultest D/memalloc﹕ ion: Unmapping buffer base:0x54242000 size:2088960
08-07 20:05:15.701 25029-25029/com.james.restfultest D/memalloc﹕ ion: Unmapping buffer base:0x4002a000 size:4096
08-07 20:05:15.701 25029-25029/com.james.restfultest D/memalloc﹕ ion: Unmapping buffer base:0x549c4000 size:2088960
08-07 20:05:15.701 25029-25029/com.james.restfultest D/memalloc﹕ ion: Unmapping buffer base:0x4002c000 size:4096
08-07 20:05:15.701 25029-25029/com.james.restfultest D/memalloc﹕ ion: Unmapping buffer base:0x54cc2000 size:2088960
08-07 20:05:15.701 25029-25029/com.james.restfultest D/memalloc﹕ ion: Unmapping buffer base:0x40033000 size:4096
我的代码如下: 主要活动:
package com.james.restfultest;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
//Consume Service
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.AsyncTask;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.StatusLine;
import org.apache.http.client.HttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.springframework.web.client.RestTemplate;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import android.util.Log;
import android.widget.Toast;
import org.apache.http.impl.client.DefaultHttpClient;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpGet;
//Client SSL
import java.security.KeyStore;
import org.apache.http.conn.ssl.SSLSocketFactory;
import java.io.InputStream;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.cookie.Cookie;
import org.apache.http.protocol.HTTP;
public class Main extends Activity {
EditText edtInput;
Button btnGo;
TextView txvOutput;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setEventHandlers();
// check if you are connected or not
if (isConnected()) {
edtInput.setBackgroundColor(0xFF00CC00);
} else {
edtInput.setBackgroundColor(0xFF333333);
}
}
@Override
protected void onStart() {
super.onStart();
//new HttpRequestTask().execute();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
private void setEventHandlers() {
edtInput = (EditText) findViewById(R.id.edtInput);
btnGo = (Button) findViewById(R.id.btnGo);
txvOutput = (TextView) findViewById(R.id.txvOutput);
btnGo.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
try {
callRestService(edtInput.getText().toString());
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public boolean isConnected() {
ConnectivityManager connMgr = (ConnectivityManager) getSystemService(Activity.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
if (networkInfo != null && networkInfo.isConnected())
return true;
else
return false;
}
private void callRestService(String sParam) throws Exception {
MyAsyncTask myAsync = new MyAsyncTask();
myAsync.RefreshRefPoints(this, this);
myAsync.execute("hello", "boys");
}
}
class MyAsyncTask extends AsyncTask<String, Integer, String>{
public Context myContext;
public Activity myActivity;
public void RefreshRefPoints(Context ctx, Activity act){
// Now set context
this.myContext = ctx;
this.myActivity = act;
}
@Override
protected String doInBackground(String... params) {
// TODO Auto-generated method stub
String s=postData(params);
return s;
}
protected void onPostExecute(String result){
//pb.setVisibility(View.GONE);
Toast.makeText(myContext, result, Toast.LENGTH_LONG).show();
}
protected void onProgressUpdate(Integer... progress){
//pb.setProgress(progress[0]);
}
public String postData(String valueIWantToSend[]) {
// Create a new HttpClient and Post Header
DefaultHttpClient httpclient = new MyHttpsClient(myContext);
HttpPost httppost = new HttpPost("https://google.com");
String origresponseText="";
try {
// Add your data
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
nameValuePairs.add(new BasicNameValuePair("param1",valueIWantToSend[0]));
nameValuePairs.add(new BasicNameValuePair("param2", valueIWantToSend[1]));
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
/* execute */
HttpResponse response = httpclient.execute(httppost);
HttpEntity rp = response.getEntity();
origresponseText=readContent(response);
}
catch (ClientProtocolException e) {
// TODO Auto-generated catch block
}
catch (IOException e) {
// TODO Auto-generated catch block
}
String responseText = origresponseText.substring(7, origresponseText.length());
return responseText;
}
String readContent(HttpResponse response)
{
String text = "";
InputStream in =null;
try {
in = response.getEntity().getContent();
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
text = sb.toString();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
finally {
try {
in.close();
} catch (Exception ex) {
}
}
return text;
}
}
和MyHttpsClient:
package com.james.restfultest;
import java.io.InputStream;
import java.security.KeyStore;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.scheme.PlainSocketFactory;
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.SingleClientConnManager;
import android.content.Context;
public class MyHttpsClient extends DefaultHttpClient {
final Context context;
public MyHttpsClient(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.servercertificate);
try {
// Initialize the keystore with the provided trusted certificates
// Also provide the password of the keystore
trusted.load(in, "myPassword".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而不是MyHttpsClient,那么这可以工作,我得到了回复,因此它与使用SSL,MyHttpsClient或我的密钥库有关。
我只是通过创建一个新的.bks密钥库并添加一个名为&#34; jamespearce&#34;的单个证书,在Portecle中创建了密钥库。它。我无法找到要测试的示例密钥库,但我可以在Portecle中打开这个密码库,所以假设它没问题。
我对这里的错误完全感到困惑,但感觉我真的很接近:有人可以让这个工作吗?
编辑:感谢Commonware,因为他在下面解决了这个问题。这是因为谷歌没有使用我的自定义证书而且我不信任他们!调用我的webservice(肯定使用与客户端相同的证书)获取以下日志:
08-07 22:19:03.722 1951-1951/com.james.restfultest E/Trace﹕ error opening trace file: No such file or directory (2)
08-07 22:19:03.963 1951-1951/com.james.restfultest I/Adreno200-EGL﹕ <qeglDrvAPI_eglInitialize:299>: EGL 1.4 QUALCOMM build: AU_LINUX_ANDROID_JB_REL_RB1.04.01.01.06.043_msm8660_surf_JB_REL_RB1.2_CL2428086_release_AU (CL2428086)
Build Date: 11/15/12 Thu
Local Branch:
Remote Branch: m/jb_rel_rb1.2
Local Patches: NONE
Reconstruct Branch: AU_LINUX_ANDROID_JB_REL_RB1.04.01.01.06.043 + e534df6 + 951c251 + 07bf631 + 6aa3ec7 + e04e486 + 9f5646a + 855d11b + NOTHING
08-07 22:19:03.993 1951-1951/com.james.restfultest D/memalloc﹕ ion: Mapped buffer base:0x54242000 size:2088960 offset:0 fd:61
08-07 22:19:03.993 1951-1951/com.james.restfultest D/memalloc﹕ ion: Mapped buffer base:0x4002a000 size:4096 offset:0 fd:63
08-07 22:19:04.133 1951-1951/com.james.restfultest D/memalloc﹕ ion: Mapped buffer base:0x549c4000 size:2088960 offset:0 fd:66
08-07 22:19:04.133 1951-1951/com.james.restfultest D/memalloc﹕ ion: Mapped buffer base:0x4002c000 size:4096 offset:0 fd:68
08-07 22:19:04.553 1951-1951/com.james.restfultest D/memalloc﹕ ion: Mapped buffer base:0x54cc2000 size:2088960 offset:0 fd:70
08-07 22:19:04.553 1951-1951/com.james.restfultest D/memalloc﹕ ion: Mapped buffer base:0x40033000 size:4096 offset:0 fd:72
08-07 22:19:23.982 1951-1951/com.james.restfultest D/memalloc﹕ ion: Unmapping buffer base:0x54242000 size:2088960
08-07 22:19:23.982 1951-1951/com.james.restfultest D/memalloc﹕ ion: Unmapping buffer base:0x4002a000 size:4096
08-07 22:19:23.982 1951-1951/com.james.restfultest D/memalloc﹕ ion: Unmapping buffer base:0x549c4000 size:2088960
08-07 22:19:23.982 1951-1951/com.james.restfultest D/memalloc﹕ ion: Unmapping buffer base:0x4002c000 size:4096
08-07 22:19:27.926 2276-2276/com.james.restfultest E/Trace﹕ error opening trace file: No such file or directory (2)
08-07 22:19:28.146 2276-2276/com.james.restfultest I/Adreno200-EGL﹕ <qeglDrvAPI_eglInitialize:299>: EGL 1.4 QUALCOMM build: AU_LINUX_ANDROID_JB_REL_RB1.04.01.01.06.043_msm8660_surf_JB_REL_RB1.2_CL2428086_release_AU (CL2428086)
Build Date: 11/15/12 Thu
Local Branch:
Remote Branch: m/jb_rel_rb1.2
Local Patches: NONE
Reconstruct Branch: AU_LINUX_ANDROID_JB_REL_RB1.04.01.01.06.043 + e534df6 + 951c251 + 07bf631 + 6aa3ec7 + e04e486 + 9f5646a + 855d11b + NOTHING
08-07 22:19:28.176 2276-2276/com.james.restfultest D/memalloc﹕ ion: Mapped buffer base:0x54242000 size:2088960 offset:0 fd:61
08-07 22:19:28.186 2276-2276/com.james.restfultest D/memalloc﹕ ion: Mapped buffer base:0x4002a000 size:4096 offset:0 fd:63
08-07 22:19:28.316 2276-2276/com.james.restfultest D/memalloc﹕ ion: Mapped buffer base:0x54ac4000 size:2088960 offset:0 fd:66
08-07 22:19:28.316 2276-2276/com.james.restfultest D/memalloc﹕ ion: Mapped buffer base:0x4002c000 size:4096 offset:0 fd:68
08-07 22:19:28.737 2276-2276/com.james.restfultest D/memalloc﹕ ion: Mapped buffer base:0x54dc2000 size:2088960 offset:0 fd:70
08-07 22:19:28.737 2276-2276/com.james.restfultest D/memalloc﹕ ion: Mapped buffer base:0x40033000 size:4096 offset:0 fd:72
08-07 22:19:33.441 2276-2371/com.james.restfultest I/global﹕ call createSocket() return a new socket.
08-07 22:19:33.581 2276-2371/com.james.restfultest W/dalvikvm﹕ threadid=12: thread exiting with uncaught exception (group=0x41f31390)
08-07 22:19:33.601 2276-2371/com.james.restfultest E/AndroidRuntime﹕ FATAL EXCEPTION: AsyncTask #1
java.lang.RuntimeException: An error occured while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:299)
at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
at java.util.concurrent.FutureTask.run(FutureTask.java:137)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
at java.lang.Thread.run(Thread.java:864)
Caused by: java.lang.AssertionError: javax.net.ssl.SSLException: hostname in certificate didn't match: <86.168.253.152> != <james pearce>
at com.james.restfultest.MyAsyncTask.postData(Main.java:186)
at com.james.restfultest.MyAsyncTask.doInBackground(Main.java:154)
at com.james.restfultest.MyAsyncTask.doInBackground(Main.java:140)
at android.os.AsyncTask$2.call(AsyncTask.java:287)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
at java.util.concurrent.FutureTask.run(FutureTask.java:137)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
at java.lang.Thread.run(Thread.java:864)
Caused by: javax.net.ssl.SSLException: hostname in certificate didn't match: <86.168.253.152> != <james pearce>
at org.apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.java:185)
at org.apache.http.conn.ssl.StrictHostnameVerifier.verify(StrictHostnameVerifier.java:61)
at org.apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.java:114)
at org.apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.java:95)
at org.apache.http.conn.ssl.SSLSocketFactory.createSocket(SSLSocketFactory.java:381)
at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:165)
at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)
at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119)
at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:367)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:592)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:510)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:488)
at com.james.restfultest.MyAsyncTask.postData(Main.java:178)
at com.james.restfultest.MyAsyncTask.doInBackground(Main.java:154)
at com.james.restfultest.MyAsyncTask.doInBackground(Main.java:140)
at android.os.AsyncTask$2.call(AsyncTask.java:287)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
at java.util.concurrent.FutureTask.run(FutureTask.java:137)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
at java.lang.Thread.run(Thread.java:864)
08-07 22:19:34.082 2276-2276/com.james.restfultest D/memalloc﹕ ion: Unmapping buffer base:0x54242000 size:2088960
08-07 22:19:34.082 2276-2276/com.james.restfultest D/memalloc﹕ ion: Unmapping buffer base:0x4002a000 size:4096
08-07 22:19:34.092 2276-2276/com.james.restfultest D/memalloc﹕ ion: Unmapping buffer base:0x54ac4000 size:2088960
08-07 22:19:34.092 2276-2276/com.james.restfultest D/memalloc﹕ ion: Unmapping buffer base:0x4002c000 size:4096
08-07 22:19:34.092 2276-2276/com.james.restfultest D/memalloc﹕ ion: Unmapping buffer base:0x54dc2000 size:2088960
08-07 22:19:34.092 2276-2276/com.james.restfultest D/memalloc﹕ ion: Unmapping buffer base:0x40033000 size:4096
我会调查此事,但如果有人知道解决方法,请告诉我。我知道我可以使用SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER信任所有证书,但我想要做的是从任何URL信任此证书。
Commonware - 再次感谢 - 这让我很生气;-)
如果您知道如何解决此问题,请发帖作为答案,以便我给您信任。
编辑:好的,一定是睡觉的时间;-)我刚刚意识到SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER正是我需要的。