Android平台实现https信任所有证书的方法

Android平台上经常有使用https的需求,对于https服务器使用的根证书是受信任的证书的话,实现https是非常简单的,直接用httpclient库就行了,与使用http几乎没有区别。但是在大多数情况下,服务器所使用的根证书是自签名的,或者签名机构不在设备的信任证书列表中,这样使用httpclient进行https连接就会失败。解决这个问题的办法有两种,一是在发起https连接之前将服务器证书加到httpclient的信任证书列表中,这个相对来说比较复杂一些,很容易出错;另一种办法是让httpclient信任所有的服务器证书,这种办法相对来说简单很多,但安全性则差一些,但在某些场合下有一定的应用场景。这里要举例说明的就是后一种方法:实例化HttpClinet对象时要进行一些处理主要是绑定https连接所使用的端口号,这里绑定了443和8443:

[java] view plain copy
  1. SchemeRegistryschemeRegistry=newSchemeRegistry();
  2. schemeRegistry.register(newScheme("https",
  3. newEasySSLSocketFactory(),443));
  4. schemeRegistry.register(newScheme("https",
  5. newEasySSLSocketFactory(),8443));
  6. ClientConnectionManagerconnManager=newThreadSafeClientConnManager(params,schemeRegistry);
  7. HttpClienthttpClient=newDefaultHttpClient(connManager,params);


上面的EasySSLSocketFactory类是我们自定义的,主要目的就是让httpclient接受所有的服务器证书,能够正常的进行https数据读取。相关代码如下:

[java] view plain copy
  1. publicclassEasySSLSocketFactoryimplementsSocketFactory,
  2. LayeredSocketFactory{
  3. privateSSLContextsslcontext=null;
  4. privatestaticSSLContextcreateEasySSLContext()throwsIOException{
  5. try{
  6. SSLContextcontext=SSLContext.getInstance("TLS");
  7. context.init(null,newTrustManager[]{newEasyX509TrustManager(
  8. null)},null);
  9. returncontext;
  10. }catch(Exceptione){
  11. thrownewIOException(e.getMessage());
  12. }
  13. }
  14. privateSSLContextgetSSLContext()throwsIOException{
  15. if(this.sslcontext==null){
  16. this.sslcontext=createEasySSLContext();
  17. }
  18. returnthis.sslcontext;
  19. }
  20. publicSocketconnectSocket(Socketsock,Stringhost,intport,
  21. InetAddresslocalAddress,intlocalPort,HttpParamsparams)
  22. throwsIOException,UnknownHostException,ConnectTimeoutException{
  23. intconnTimeout=HttpConnectionParams.getConnectionTimeout(params);
  24. intsoTimeout=HttpConnectionParams.getSoTimeout(params);
  25. InetSocketAddressremoteAddress=newInetSocketAddress(host,port);
  26. SSLSocketsslsock=(SSLSocket)((sock!=null)?sock:createSocket());
  27. if((localAddress!=null)||(localPort>0)){
  28. //weneedtobindexplicitly
  29. if(localPort<0){
  30. localPort=0;//indicates"any"
  31. }
  32. InetSocketAddressisa=newInetSocketAddress(localAddress,
  33. localPort);
  34. sslsock.bind(isa);
  35. }
  36. sslsock.connect(remoteAddress,connTimeout);
  37. sslsock.setSoTimeout(soTimeout);
  38. returnsslsock;
  39. }
  40. publicSocketcreateSocket()throwsIOException{
  41. returngetSSLContext().getSocketFactory().createSocket();
  42. }
  43. publicbooleanisSecure(Socketsocket)throwsIllegalArgumentException{
  44. returntrue;
  45. }
  46. publicSocketcreateSocket(Socketsocket,Stringhost,intport,
  47. booleanautoClose)throwsIOException,UnknownHostException{
  48. returngetSSLContext().getSocketFactory().createSocket(socket,host,
  49. port,autoClose);
  50. }
  51. //-------------------------------------------------------------------
  52. //javadocinorg.apache.http.conn.scheme.SocketFactorysays:
  53. //BothObject.equals()andObject.hashCode()mustbeoverridden
  54. //forthecorrectoperationofsomeconnectionmanagers
  55. //-------------------------------------------------------------------
  56. publicbooleanequals(Objectobj){
  57. return((obj!=null)&&obj.getClass().equals(
  58. EasySSLSocketFactory.class));
  59. }
  60. publicinthashCode(){
  61. returnEasySSLSocketFactory.class.hashCode();
  62. }
  63. }
  64. publicclassEasyX509TrustManagerimplementsX509TrustManager{
  65. privateX509TrustManagerstandardTrustManager=null;
  66. publicEasyX509TrustManager(KeyStorekeystore)
  67. throwsNoSuchAlgorithmException,KeyStoreException{
  68. super();
  69. TrustManagerFactoryfactory=TrustManagerFactory
  70. .getInstance(TrustManagerFactory.getDefaultAlgorithm());
  71. factory.init(keystore);
  72. TrustManager[]trustmanagers=factory.getTrustManagers();
  73. if(trustmanagers.length==0){
  74. thrownewNoSuchAlgorithmException("notrustmanagerfound");
  75. }
  76. this.standardTrustManager=(X509TrustManager)trustmanagers[0];
  77. }
  78. publicvoidcheckClientTrusted(X509Certificate[]certificates,
  79. StringauthType)throwsCertificateException{
  80. standardTrustManager.checkClientTrusted(certificates,authType);
  81. }
  82. publicvoidcheckServerTrusted(X509Certificate[]certificates,
  83. StringauthType)throwsCertificateException{
  84. if((certificates!=null)&&(certificates.length==1)){
  85. certificates[0].checkValidity();
  86. }else{
  87. standardTrustManager.checkServerTrusted(certificates,authType);
  88. }
  89. }
  90. publicX509Certificate[]getAcceptedIssuers(){
  91. returnthis.standardTrustManager.getAcceptedIssuers();
  92. }
  93. }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值