由于互联网全面普及,未来网络安全这块的发展空间很大的。随着物联网的不断应用,人们的生活和网络已经密不可分,网络上承载着数以亿计的各种信息,这些数据信息是个人、企业甚至是国家的战略性资源,所以保障他们的安全是一件非常重要的事情。因此,在未来,各个企业定会在网络安全这块倾尽余力。
所以为了保障网络安全,最近公司也在做双向验证的https接口,和其它企业进行对接。但是发现网上针对双向验证的资料少之又少,大部分还是单向验证,还有些博客是用绕过验证的方式提交数据,并且有些博客还是错误的。按照其他博客的方法操作不但不能实现,反而还浪费了大量的时间。本文章只针对前端(Android)端的操作进行解读,后台的配置会简略的说明。
本文章只针对自制证书进行解读。双向SSL主要是看后台的设计,双向验证有两个证书,一个是根证书,一个是客户端证书。根证书由后台生成,客户端证书也可以安排由后台生成。证书的生成可以参考次链接(点击此处)。生成的证书格式为jks。但是android证书类型不支持解析jks文件,我们需要通过转换工具 https://download.csdn.net/download/z879381359/11225612 下载次工具,进行格式转换。
将两个jks转换成bks,然后再把资源放到android的assets目录中
所有工作就已经准备就绪,开始写代码了
补充:代码用的是databinding没有或者不熟悉的话大伙们要改成findviewbyId哦,
导入包:
implementation "com.squareup.retrofit2:converter-scalars:2.3.0"
implementation "com.squareup.retrofit2:converter-gson:2.3.0"
implementation "com.squareup.okhttp3:logging-interceptor:3.8.1"
主类
public class TestActivity extends Activity {
private TestActivityBinding binding;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.binding = DataBindingUtil.setContentView(this, R.layout.test_activity);
this.binding.setActivity(this);
this.binding.button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
query();
}
});
query();
}
@Override
protected void onDestroy() {
super.onDestroy();
}
public void query(){
String url = "https://192.168.***";
//创建日志拦截器,用于日志打印
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient okHttpClient = new OkHttpClient().newBuilder()
.addInterceptor(interceptor)
.sslSocketFactory(SSLHelper.getSSLCertifcation(this), new HttpsUtil.UnSafeTrustManager())
.hostnameVerifier(new HttpsUtil.UnSafeHostnameVerifier())//此处设置忽略掉域名校验
.build();
final Request request = new Request.Builder()
.url(url)
.get()
.build();
Call call = okHttpClient.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
LogUtils.i("请求失败:"+e.getMessage());
e.printStackTrace();
}
@Override
public void onResponse(Call call, Response response) throws IOException {
LogUtils.i("请求成功" + response.body().toString());
LogUtils.i("请求成功" + response.message());
}
});
}
}
SSLHelper
public class SSLHelper {
private static final String TAG = "SSLHelper";
private final static String CLIENT_PRI_KEY = "nk_client.bks";
private final static String TRUSTSTORE_PUB_KEY = "nk_server.bks";
private final static String CLIENT_BKS_PASSWORD = "123456";
private final static String TRUSTSTORE_BKS_PASSWORD = "123456";
private final static String KEYSTORE_TYPE = "BKS";
private final static String PROTOCOL_TYPE = "TLS";
private final static String CERTIFICATE_STANDARD = "X509";
public static SSLSocketFactory getSSLCertifcation(Context context) {
SSLSocketFactory sslSocketFactory = null;
try {
// 服务器端需要验证的客户端证书,其实就是客户端的keystore
KeyStore keyStore = KeyStore.getInstance(KEYSTORE_TYPE);
// 客户端信任的服务器端证书
KeyStore trustStore = KeyStore.getInstance(KEYSTORE_TYPE);
//读取证书
InputStream ksIn = context.getAssets().open(CLIENT_PRI_KEY);
InputStream tsIn = context.getAssets().open(TRUSTSTORE_PUB_KEY);
//加载证书
keyStore.load(ksIn, CLIENT_BKS_PASSWORD.toCharArray());
trustStore.load(tsIn, TRUSTSTORE_BKS_PASSWORD.toCharArray());
ksIn.close();
tsIn.close();
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(CERTIFICATE_STANDARD);
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(CERTIFICATE_STANDARD);
trustManagerFactory.init(trustStore);
keyManagerFactory.init(keyStore, CLIENT_BKS_PASSWORD.toCharArray());
//初始化SSLContext
SSLContext sslContext = SSLContext.getInstance(PROTOCOL_TYPE);
sslContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), new java.security.SecureRandom());
sslSocketFactory = sslContext.getSocketFactory();
} catch (KeyStoreException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (CertificateException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (UnrecoverableKeyException e) {
e.printStackTrace();
} catch (KeyManagementException e) {
e.printStackTrace();
}
return sslSocketFactory;
}
}
HttpsUtil
public class HttpsUtil {
public static class SSLParams
{
public SSLSocketFactory sSLSocketFactory;
public X509TrustManager trustManager;
}
public static SSLParams getSslSocketFactory(InputStream[] certificates, InputStream bksFile, String password)
{
SSLParams sslParams = new SSLParams();
try
{
TrustManager[] trustManagers = prepareTrustManager(certificates);
KeyManager[] keyManagers = prepareKeyManager(bksFile, password);
SSLContext sslContext = SSLContext.getInstance("TLS");
X509TrustManager trustManager = null;
if (trustManagers != null)
{
trustManager = new MyTrustManager(chooseTrustManager(trustManagers));
} else
{
trustManager = new UnSafeTrustManager();
}
sslContext.init(keyManagers, new TrustManager[]{trustManager},null);
sslParams.sSLSocketFactory = sslContext.getSocketFactory();
sslParams.trustManager = trustManager;
return sslParams;
} catch (NoSuchAlgorithmException e)
{
throw new AssertionError(e);
} catch (KeyManagementException e)
{
throw new AssertionError(e);
} catch (KeyStoreException e)
{
throw new AssertionError(e);
}
}
public static class UnSafeHostnameVerifier implements HostnameVerifier
{
@Override
public boolean verify(String hostname, SSLSession session)
{
return true;
}
}
public static class UnSafeTrustManager implements X509TrustManager
{
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType)
throws CertificateException
{
}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType)
throws CertificateException
{
}
@Override
public X509Certificate[] getAcceptedIssuers()
{
return new X509Certificate[]{};
}
}
private static TrustManager[] prepareTrustManager(InputStream... certificates)
{
if (certificates == null || certificates.length <= 0) return null;
try
{
CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(null);
int index = 0;
for (InputStream certificate : certificates)
{
String certificateAlias = Integer.toString(index++);
keyStore.setCertificateEntry(certificateAlias, certificateFactory.generateCertificate(certificate));
try
{
if (certificate != null)
certificate.close();
} catch (IOException e)
{
}
}
TrustManagerFactory trustManagerFactory = null;
trustManagerFactory = TrustManagerFactory.
getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(keyStore);
TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
return trustManagers;
} catch (NoSuchAlgorithmException e)
{
e.printStackTrace();
} catch (CertificateException e)
{
e.printStackTrace();
} catch (KeyStoreException e)
{
e.printStackTrace();
} catch (Exception e)
{
e.printStackTrace();
}
return null;
}
private static KeyManager[] prepareKeyManager(InputStream bksFile, String password)
{
try
{
if (bksFile == null || password == null) return null;
KeyStore clientKeyStore = KeyStore.getInstance("BKS");
clientKeyStore.load(bksFile, password.toCharArray());
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
keyManagerFactory.init(clientKeyStore, password.toCharArray());
return keyManagerFactory.getKeyManagers();
} catch (KeyStoreException e)
{
e.printStackTrace();
} catch (NoSuchAlgorithmException e)
{
e.printStackTrace();
} catch (UnrecoverableKeyException e)
{
e.printStackTrace();
} catch (CertificateException e)
{
e.printStackTrace();
} catch (IOException e)
{
e.printStackTrace();
} catch (Exception e)
{
e.printStackTrace();
}
return null;
}
private static X509TrustManager chooseTrustManager(TrustManager[] trustManagers)
{
for (TrustManager trustManager : trustManagers)
{
if (trustManager instanceof X509TrustManager)
{
return (X509TrustManager) trustManager;
}
}
return null;
}
private static class MyTrustManager implements X509TrustManager
{
private X509TrustManager defaultTrustManager;
private X509TrustManager localTrustManager;
public MyTrustManager(X509TrustManager localTrustManager) throws NoSuchAlgorithmException, KeyStoreException
{
TrustManagerFactory var4 = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
var4.init((KeyStore) null);
defaultTrustManager = chooseTrustManager(var4.getTrustManagers());
this.localTrustManager = localTrustManager;
}
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException
{
}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException
{
try
{
defaultTrustManager.checkServerTrusted(chain, authType);
} catch (CertificateException ce)
{
localTrustManager.checkServerTrusted(chain, authType);
}
}
@Override
public X509Certificate[] getAcceptedIssuers()
{
return new X509Certificate[0];
}
}
}
Android端的工作就完成啦。文章要是有误,欢迎大家来在下方评论。
————————————————
版权声明:本文为CSDN博主「z879381359」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/z879381359/article/details/90774627