java自动获取安装在线数字证书

java自动获取安装在线数字证书

主要原理是:使用socket尝试对目标服务器进行通信,如果通信失败,证明没有证书,不过此时的证书已悄悄发送到客户端了。

以前写过这个工具类了: http://leisuredev.iteye.com/admin/blogs/714742
今天稍微注释并整理了一个版本:

  1  package  com.leisure.cert;
  2 
  3  import  java.io.File;
  4  import  java.io.FileInputStream;
  5  import  java.io.FileOutputStream;
  6  import  java.io.InputStream;
  7  import  java.io.OutputStream;
  8  import  java.security.KeyStore;
  9  import  java.security.cert.CertificateException;
 10  import  java.security.cert.X509Certificate;
 11 
 12  import  javax.net.ssl.HostnameVerifier;
 13  import  javax.net.ssl.HttpsURLConnection;
 14  import  javax.net.ssl.SSLContext;
 15  import  javax.net.ssl.SSLSession;
 16  import  javax.net.ssl.SSLSocket;
 17  import  javax.net.ssl.SSLSocketFactory;
 18  import  javax.net.ssl.TrustManager;
 19  import  javax.net.ssl.TrustManagerFactory;
 20  import  javax.net.ssl.X509TrustManager;
 21 
 22  /**
 23   * 
 24   * Java在线自动获取并安装证书工具类
 25   *  @author  Leisure
 26   *  @version  1.1
 27   * 
 28    */
 29  public   class  CertManager {
 30 
 31       public   static   void  main(String[] args) {
 32           try  {
 33              trustCert( " d:\\ " " www.google.com.hk " 443 " changeit " );
 34          }  catch  (Exception e) {
 35              e.printStackTrace();
 36          }
 37      }
 38      
 39       /**
 40       * 
 41       *  @param  dir        证书所在路径
 42       *  @param  host        主机地址
 43       *  @param  port        端口
 44       *  @param  password    证书密码
 45       *  @throws  Exception
 46        */
 47       public   static   void  trustCert(String dir, String host,  int  port, String password)  throws  Exception {
 48           //  如果证书颂给的名称与所通信的域名不一致的话,那么需要重写校验方法
 49          HostnameVerifier hv  =   new  HostnameVerifier() {
 50              @Override
 51               public   boolean  verify(String urlHostName, SSLSession session) {
 52                   return  urlHostName.equals(session.getPeerHost());
 53              }
 54          };
 55          HttpsURLConnection.setDefaultHostnameVerifier(hv);
 56 
 57           //  信任管理器工厂
 58          TrustManagerFactory tmf  =  TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
 59          File file  =   new  File(dir  +  host  +   " .cer " );
 60          file  =  makeSureFile(file);
 61          KeyStore ks  =  getKeyStore(file, password);
 62          tmf.init(ks);
 63          
 64          SSLContext context  =  SSLContext.getInstance( " SSL " );
 65          X509TrustManager defaultTrustManager  =  (X509TrustManager) tmf.getTrustManagers()[ 0 ];
 66          SavingTrustManager tm  =   new  SavingTrustManager(defaultTrustManager);
 67          context.init( null new  TrustManager[] { tm },  null );
 68          
 69           //  尝试使用socket对目标主机进行通信
 70          SSLSocketFactory factory  =  context.getSocketFactory();        
 71          SSLSocket socket  =  (SSLSocket)factory.createSocket(host, port);
 72          socket.setSoTimeout( 1000 );
 73           try  {
 74               //  如果直接通信没问题的话,就不会报错,也不必获取证书
 75               //  如果报错的话,很有可能没有证书
 76              socket.startHandshake();
 77          }  catch (Exception e) {
 78              e.printStackTrace();
 79          }  finally  {
 80               if (socket  !=   null ) {
 81                   try  {
 82                      socket.close();
 83                  }  catch (Exception e) {}        
 84                  socket  =   null ;
 85              }
 86              X509Certificate[] chain  =  tm.getChain();
 87               if (chain  !=   null ) {
 88                  System.out.println( " 服务器返回: "   +  chain.length  +   "  个证书 " );
 89                  OutputStream out  =   null ;
 90                   for ( int  i  =   0 ; i  <  chain.length; i ++ ) {
 91                       try  {                        
 92                          X509Certificate x509Cert  =  chain[i];
 93                          String alias  =  host  +  (i  >   0   ?  i  +   ""  :  "" );
 94                          ks.setCertificateEntry(alias, x509Cert);
 95                          
 96                          String certFile  =  dir  +  alias  +   " .cer " ;
 97                          out  =   new  FileOutputStream(certFile);
 98                          ks.store(out, password.toCharArray());
 99                          out.close();
100                          
101                          System.setProperty( " javax.net.ssl.trustStore " , certFile);
102                          System.out.println( " "   +  (i  +   1 +   " 个证书安装成功 " );
103                      }  catch (Exception e) {
104                          e.printStackTrace();
105                           continue ;
106                      }  finally  {
107                           try  {
108                               if (out  !=   null ) {
109                                  out.close();
110                              }
111                              out  =   null ;
112                          }  catch (Exception e) {}
113                      }
114                  }
115              }
116          }
117      }
118      
119       /**
120       * 确保文件存在
121       *  @param  file
122       *  @return
123        */
124       private   static  File makeSureFile(File file) {
125           if  (file.isFile()  ==   false ) {
126               char  SEP  =  File.separatorChar;
127              File dir  =   new  File(System.getProperty( " java.home " +  SEP  +   " lib "      +  SEP  +   " security " );
128              file  =   new  File(dir, file.getName());
129               if  (file.isFile()  ==   false ) {
130                  file  =   new  File(dir,  " cacerts " );
131              }
132          }
133           return  file;
134      }
135      
136       /**
137       * 获取keystore
138       *  @param  file
139       *  @param  password
140       *  @return
141       *  @throws  Exception
142        */
143       private   static  KeyStore getKeyStore(File file, String password)  throws  Exception {
144          InputStream in  =   new  FileInputStream(file);
145          KeyStore ks  =  KeyStore.getInstance(KeyStore.getDefaultType());
146           char [] passphrase  =  password.toCharArray();
147          ks.load(in, passphrase);
148          in.close();
149           return  ks;
150      }
151      
152       public   static   class  SavingTrustManager  implements  X509TrustManager {
153           private   final  X509TrustManager tm;
154           private  X509Certificate[] chain;
155 
156           public  SavingTrustManager(X509TrustManager tm) {
157               this .tm  =  tm;
158          }
159          
160           public  X509TrustManager getTM() {
161               return  tm;
162          }
163          
164           public  X509Certificate[] getChain() {
165               return  chain;
166          }
167          
168           public  X509Certificate[] getAcceptedIssuers() {
169               throw   new  UnsupportedOperationException();
170          }
171 
172           public   void  checkClientTrusted(X509Certificate[] chain, String authType)
173                   throws  CertificateException {
174               throw   new  UnsupportedOperationException();
175          }
176 
177           public   void  checkServerTrusted(X509Certificate[] chain, String authType)
178                   throws  CertificateException {
179               this .chain  =  chain;
180              tm.checkServerTrusted(chain, authType);
181          }
182      }
183  }
184 

你可能感兴趣的:(java自动获取安装在线数字证书)