如何解决android中的握手异常和认证异常
Posted
技术标签:
【中文标题】如何解决android中的握手异常和认证异常【英文标题】:How resolve Handshake Exception and Certification Exception in android 【发布时间】:2016-04-08 02:09:19 【问题描述】:我想使用 https 访问 Web 服务,其证书将存储在服务器而不是应用程序上,我已经在我的信任管理器和 HostNameVerfier 中创建了一个密钥库,正如在堆栈溢出的许多问题中给出的那样,但我仍然得到访问 Web 服务时出现握手异常和证书异常。
我的证书扩展名是 .der。
这是我的代码
类 SendEncryptedData 扩展 AsyncTask ProgressDialog 对话框;
@Override
protected void onPreExecute()
super.onPreExecute();
dialog = new ProgressDialog(LoginActivity.this);
dialog.show();
@Override
protected String doInBackground(Object[] params)
TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
String DeviceId = telephonyManager.getDeviceId();
try
HttpParams client = new BasicHttpParams();
final SchemeRegistry schemeRegistry = new SchemeRegistry();
schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
schemeRegistry.register(new Scheme("https", createAdditionalCertsSSLSocketFactory(), 443));
HttpProtocolParams.setVersion(client, HttpVersion.HTTP_1_1);
ThreadSafeClientConnManager singleClientConnManager = new ThreadSafeClientConnManager(client,schemeRegistry);
DefaultHttpClient defaultHttpClient = new DefaultHttpClient(singleClientConnManager,client);
HttpPost httpPost = new HttpPost(URL);
JSONObject jsonObject = new JSONObject();
jsonObject.accumulate("device",DeviceId);
jsonObject.accumulate("login", encryptedEmail);
jsonObject.accumulate("password", encryptedPassword);
StringEntity stringEntity = new StringEntity(jsonObject.toString());
httpPost.setEntity(stringEntity);
HttpResponse httpResponse = defaultHttpClient.execute(httpPost);
int statusCode= httpResponse.getStatusLine().getStatusCode();
String response = httpResponse.getEntity().getContent().toString();
catch (IOException e)
e.printStackTrace();
catch (Exception ex)
ex.printStackTrace();
@Override
protected void onPostExecute(Object o)
super.onPostExecute(o);
dialog.dismiss();
startActivity(new Intent(LoginActivity.this, MainActivity.class));
protected org.apache.http.conn.ssl.SSLSocketFactory createAdditionalCertsSSLSocketFactory()
try
final KeyStore ks = KeyStore.getInstance("BKS");
// the bks file we generated above
final InputStream in = getResources().openRawResource( R.raw.analec);
try
// don't forget to put the password used above in strings.xml/mystore_password
ks.load(in, "password".toCharArray());
finally
in.close();
return new AdditionalKeyStoresSSLSocketFactory(ks);
catch( Exception e )
throw new RuntimeException(e);
public class AdditionalKeyStoresSSLSocketFactory extends SSLSocketFactory
protected SSLContext sslContext = SSLContext.getInstance("TLS");
public AdditionalKeyStoresSSLSocketFactory(KeyStore keyStore) throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException
super(null, null, null, null, null, null);
sslContext.init(null, new TrustManager[]new AdditionalKeyStoresTrustManager(keyStore), null);
@Override
public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException
return sslContext.getSocketFactory().createSocket(socket, host, port, autoClose);
@Override
public Socket createSocket() throws IOException
return sslContext.getSocketFactory().createSocket();
/**
* Based on http://download.oracle.com/javase/1.5.0/docs/guide/security/jsse/JSSERefGuide.html#X509TrustManager
*/
public static class AdditionalKeyStoresTrustManager implements X509TrustManager
protected ArrayList<X509TrustManager> x509TrustManagers = new ArrayList<X509TrustManager>();
protected AdditionalKeyStoresTrustManager(KeyStore... additionalkeyStores)
final ArrayList<TrustManagerFactory> factories = new ArrayList<TrustManagerFactory>();
try
// The default Trustmanager with default keystore
final TrustManagerFactory original = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
original.init((KeyStore) null);
factories.add(original);
for( KeyStore keyStore : additionalkeyStores )
final TrustManagerFactory additionalCerts = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
additionalCerts.init(keyStore);
factories.add(additionalCerts);
catch (Exception e)
throw new RuntimeException(e);
/*
* Iterate over the returned trustmanagers, and hold on
* to any that are X509TrustManagers
*/
for (TrustManagerFactory tmf : factories)
for( TrustManager tm : tmf.getTrustManagers() )
if (tm instanceof X509TrustManager)
x509TrustManagers.add( (X509TrustManager)tm );
if( x509TrustManagers.size()==0 )
throw new RuntimeException("Couldn't find any X509TrustManagers");
/*
* Delegate to the default trust manager.
*/
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException
final X509TrustManager defaultX509TrustManager = x509TrustManagers.get(0);
defaultX509TrustManager.checkClientTrusted(chain, authType);
/*
* Loop over the trustmanagers until we find one that accepts our server
*/
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException
for( X509TrustManager tm : x509TrustManagers )
try
tm.checkServerTrusted(chain,authType);
return;
catch( CertificateException e )
// ignore
throw new CertificateException();
public X509Certificate[] getAcceptedIssuers()
final ArrayList<X509Certificate> list = new ArrayList<X509Certificate>();
for( X509TrustManager tm : x509TrustManagers )
list.addAll(Arrays.asList(tm.getAcceptedIssuers()));
return list.toArray(new X509Certificate[list.size()]);
请告诉我如何解决这些问题。
【问题讨论】:
【参考方案1】:这是一个临时解决方案,您可以在测试调试版本之前核对 ssl 证书,或者找到更好的解决方案
public static class NukeSSLCerts
protected static final String TAG = "NukeSSLCerts";
public static void nuke()
try
TrustManager[] trustAllCerts = new TrustManager[]
new X509TrustManager()
public X509Certificate[] getAcceptedIssuers()
X509Certificate[] myTrustedAnchors = new X509Certificate[0];
return myTrustedAnchors;
@Override
public void checkClientTrusted(X509Certificate[] certs, String authType)
@Override
public void checkServerTrusted(X509Certificate[] certs, String authType)
;
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier()
@Override
public boolean verify(String arg0, SSLSession arg1)
return true;
);
catch (Exception e)
【讨论】:
查看这篇文章***.com/questions/15762249/… 我没有使用 Soap 服务。 这可以帮助你codeproject.com/Articles/826045/…以上是关于如何解决android中的握手异常和认证异常的主要内容,如果未能解决你的问题,请参考以下文章
如何解决空指针异常和 ThreadException 中的错误android
如何解决空指针异常和 ThreadException 中的错误android
[Android]异常4-javax.mail.AuthenticationFailedException
如何修复 Android 模拟器中的“无法连接到相机服务”异常