前面我们面对https自签证书的方式是在客户端放入一份服务器的证书文件,在访问网络的情况下使用去验证。但是实际上通过浏览器访问时,如果该网站为HTTPS网站,浏览器会自动检测系统中是否存在该网站的信任证书, 如果没有信任证书,浏览器一般会拒绝访问但是也会有一个继续访问的操作,但地址栏是红色,给予用户警示作用, 即客户端验证服务端并不是强制性的,可以没有服务端的信任证书,当然是否继续访问完全取决于用户自己。 如果要去除地址栏的红色警告,需要导入服务端提供的证书到浏览器中。
双向认证即服务端要验证客户端的证书,客户端要验证服务端的证书,缺一不可。前面的方式等同于只做了客户端验证服务端的证书,现在我们要加上一个证书在客户端,在访问的时候带上这个证书,如果这个客户端的证书在服务器的证书库中,则验证通过,可以继续访问,反之无法显示页面,因为服务器无法向客户端一样自己选择信任该客户端所以无法绕过。
appClient.p12 客户端的证书
appServer.p12 服务端的证书 证书类型都是PKCS12
配置证书的代码如下
private OkHttpClient.BuildersetCertificates1(OkHttpClient.Builder client, InputStream... certificates) {
try {
// 服务器端需要验证的客户端证书 PKCS12
keyStore = KeyStore.getInstance(KEY_STORE_TYPE_P12);
// 客户端信任的服务器端证书
trustStore = KeyStore.getInstance(KEY_STORE_TYPE_P12);
InputStream ksIn = getAssets().open("appClient.p12");
InputStream tsIn = getAssets().open("appServer.p12");
try {
keyStore.load(ksIn, clientPasssword.toCharArray());
trustStore.load(tsIn, serverPassword.toCharArray());
}catch (Exception e) {
e.printStackTrace();
}finally {
try {
ksIn.close();
}catch (Exception ignore) {
}
try {
tsIn.close();
}catch (Exception ignore) {
}
}
SSLContext sslContext = SSLContext.getInstance("TLS");
TrustManagerFactory trustManagerFactory =
TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(trustStore);
KeyManagerFactory keyManagerFactory=KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
keyManagerFactory.init(keyStore,clientPasssword.toCharArray());
sslContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), new SecureRandom());
SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
X509TrustManager trustManager = Platform.get().trustManager(sslSocketFactory);
client.sslSocketFactory(sslSocketFactory, trustManager);
}catch (KeyManagementException e) {
e.printStackTrace();
}catch (UnrecoverableKeyException e) {
e.printStackTrace();
}catch (KeyStoreException e) {
e.printStackTrace();
}catch (FileNotFoundException e) {
e.printStackTrace();
}catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}catch (Exception e){
e.printStackTrace();
}
return client;
}