发布时间:2023-12-27 11:30
在学校Java网络编程的时候,都会接触到Socket,Socket是基于TCP的数据传输方式,但Socket是没有证书认证的,它无法建立带证书认证的连接。还好,Java中提供了带证书认证的SSLsocket。
最近需要做一个客户端认证的需求,我需要在客户端配置自己的证书,然后向服务器发送数据,本文主要用于记录。
SSL证书的格式有很多,有.p12证书,.crt+.key证书,还有.jks证书,网上大多数案例都是基于.jks证书去实现认证,如果你的证书类型是.p12证书或者是crt证书,你可以手动把p12证书转换成jks证书,如果你是crt证书,下面会提供一个crt证书转换成jks证书的方法。
public class KeyStoreUtils {
public void generateKeyStore(String privatePath, String certPath, String ksPath, String password) throws Exception {
KeyStore var17 = KeyStore.getInstance(\"PKCS12\");
var17.load((InputStream) null, (char[]) null);
byte[] bytes = null;
PrivateKey key = getPrivateKeyFromPem(privatePath);
Certificate certificate = readCert(certPath);
var17.setKeyEntry(\"Eric\'s Key\", key, (char[]) null, new Certificate[]{certificate});
//加载证书链所有证书
var17.setKeyEntry(\"Eric\'s Key\", key, (char[]) null, certificates);
FileOutputStream var18 = new FileOutputStream(ksPath);
var17.store(var18, password.toCharArray());
var18.flush();
}
// 获取私匙
public static PrivateKey getPrivateKeyFromPem(String privateFile) throws Exception {
BufferedReader br = new BufferedReader(new FileReader(new File(privateFile)));
String s = br.readLine();
String str = \"\";
s = br.readLine();
while (s.charAt(0) != \'-\') {
str += s + \"\\r\";
s = br.readLine();
}
BASE64Decoder base64decoder = new BASE64Decoder();
byte[] b = base64decoder.decodeBuffer(str);
// 生成私匙
KeyFactory kf = KeyFactory.getInstance(PropertiesReader.getKey(\"cert_encryption\"));
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(b);
PrivateKey privateKey = kf.generatePrivate(keySpec);
return privateKey;
}
public static Certificate readCert(String certPath) throws Exception {
CertificateFactory cf = CertificateFactory.getInstance(\"X.509\");
FileInputStream in1 = new FileInputStream(certPath);
Collection<? extends Certificate> certificates = cf.generateCertificates(in1);
Iterator<? extends Certificate> iterator = certificates.iterator();
Certificate next = iterator.next();
return next;
}
public static void main(String[] args) throws Exception{
KeyStoreUtils keyStoreUtils = new KeyStoreUtils();
keyStoreUtils.generateKeyStore(\"./certificate/client_dev.key\",\"./certificate/client_dev.crt\",\"./certificate/client_dev.jks\",\"123456\");
}
}
SSLContext:SSLContext类可以创建SSLSocket实例,在这个类中配置自己的证书和自己所信任的证书。
KeyManagerFactory:加载自己的证书文件,并且生成KeyManager[]数据,配置到SSLContext。
TrustManagerFactory:加载自己信任的客户端证书,双向认证的时候配置自己信任哪些服务端证书。
KeyStore:加载证书的类。
TrustManager[]:信任的证书信任的Manager数组。
Manager[]:自己的证书的Manager数组。
代码如下,通过KeyStore去加载证书,这里我客户端证书和信任的服务器证书读的同一个,真实情况肯定是两个不一样的证书。
代码:
SSLContext ctx = SSLContext.getInstance(\"SSL\");
KeyManagerFactory kmf = KeyManagerFactory.getInstance(\"SunX509\");
TrustManagerFactory tmf = TrustManagerFactory.getInstance(\"SunX509\");
KeyStore ks = KeyStore.getInstance(\"JKS\");
tks.load(new FileInputStream(\"C://\"), \"password\".toCharArray());
kmf.init(ks, new char[0]);
kmf.init(ks, \"passworld\".toCharArray());
tmf.init(tks);
ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
log.info(\"创建sslsocket连接中。。。。。。\");
sslSocket = (SSLSocket) ctx.getSocketFactory().createSocket(\"121.0.0.1\", 8000);
如果只需要配置客户端证书,客户端信任所有服务器方的证书,可以这样配置。
把TrustManager通过如下方式生成,定义一个类继续TrustManager,X509TrustManager类。
TrustManager[] trustAllCerts = new TrustManager[1];
TrustManager tm = new miTM();
trustAllCerts[0] = tm;
static class miTM implements TrustManager,X509TrustManager {
@Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
public boolean isServerTrusted(X509Certificate[] certs) {
return true;
}
public boolean isClientTrusted(X509Certificate[] certs) {
return true;
}
@Override
public void checkServerTrusted(X509Certificate[] certs, String authType)
throws CertificateException {
return;
}
@Override
public void checkClientTrusted(X509Certificate[] certs, String authType)
throws CertificateException {
return;
}
}
ctx.init(kmf.getKeyManagers(), trustAllCerts, null);
跟Xilinx SAE 学HLS系列视频讲座笔记(2)——编写高效的C Test Bench
微信小程序:王者荣耀战力查询微信小程序源码下载支持安卓苹果微信QQ等多区查询
110.网络安全渗透测试—[权限提升篇8]—[Windows SqlServer xp_cmdshell存储过程提权]
truffle (ETH以太坊智能合约集成开发工具) 入门教程
JAVA面试都有Spring考题,还有必要去考Spring认证(证书)吗?
第二十二:Python3+Selenium2+Pytest+Pytest-Html的UI自动化测试实战实例(二)
python get请求 url_python实现http get请求