leisure

JAVA - exceed,helloworld
随笔 - 50, 文章 - 0, 评论 - 11, 引用 - 0
数据加载中……

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(nullnew 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 

posted on 2011-09-18 23:36 leisure 阅读(2276) 评论(0)  编辑  收藏 所属分类: java


只有注册用户登录后才能发表评论。


网站导航: