本人开了家网店,,店名:,是搞话费充值的,可以充值全国所有地区,三大运营商:,,.,全部是价处理,希望大家多多捧场,不求,只求好评.谢谢大家.
主要原理是:使用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
*
Leisure
26
*
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
*
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
*
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
*
141
*
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