[Java] 客户端不使用keytool实现单向认证SSL

预备知识

Java Socket, SSL单向认证

基本思路

服务端:使用keytool生成私钥和对应的证书。
客户端:代码生成私钥并自动添加服务端证书。

服务端

使用keytool生成keystore

keytool -genkey -v -alias <别名> -keyalg RSA -keystore <生成路径>
例:
keytool -genkey -v -alias server_ssl -keyalg RSA -keystore C:\Users\ASUS\desktop\key

导出服务端证书

keytool -export -ailas <别名> -keystore -file <证书导出路径>
例:
keytool -export -ailas server_ssl -keystore C:\Users\ASUS\desktop\key -file C:\Users\ASUS\desktop\server_key.cer

keystore文件由服务端保存。证书文件由客户端保存。

服务端代码:
System.setProperty("javax.net.ssl.trustStore", "resources/key");
SSLContext context = SSLContext.getInstance("TLS");

KeyStore ks = KeyStore.getInstance("jceks");
ks.load(new FileInputStream("resources/key"), null); //keystore文件路径

KeyManagerFactory kf = KeyManagerFactory.getInstance("SunX509");
kf.init(ks, "123123".toCharArray()); //keystore密码 (生成keystore时设置的密码)

context.init(kf.getKeyManagers(), null, null);
SSLServerSocket ss = (SSLServerSocket) context.getServerSocketFactory().createServerSocket(65510);
ss.setNeedClientAuth(false);

此时得到的SSLServerSocket即是建立在TSL上的ServerSocket,用法与普通的ServerSocket基本一致。

客户端

生成keystore并将服务端证书添加进keystore
KeyStore keyStore = KeyStore.getInstance("JKS");
keyStore.load(null, null);
CertAndKeyGen keypair = new CertAndKeyGen("RSA", "SHA1WithRSA", null);
X500Name x500Name = new X500Name("test", "test", "test", "test", "test", "cn");
keypair.generate(1024);
PrivateKey privKey = keypair.getPrivateKey();
X509Certificate[] chain = new X509Certificate[1];
chain[0] = keypair.getSelfCertificate(x500Name, new Date(), (long) validity * 24 * 60 * 60);
keyStore.setKeyEntry("alias", privKey, "password", chain);
keyStore.setCertificateEntry("bluedash-ssl-demo-server", CertificateFactory.getInstance("X.509").
generateCertificate(new FileInputStream("resources/certificate/server_key.cer"))); //服务端证书路径
keyStore.store(new FileOutputStream(file), "password"); // file为导出的keystore文件的File对象
连接服务器
System.setProperty("javax.net.ssl.trustStore", "resources/users/loginregister/key"); // 生成的keystore文件的路径
SSLSocket socket = (SSLSocket) SSLSocketFactory.getDefault().createSocket();
socket.connect(new InetSocketAddress(ip, port), 3000);
// socket.setNeedClientAuth(false);

此时得到的SSLSocket对象就是建立在TSL上的Socket,其用法与普通的Socket基本一致。

你可能感兴趣的:(java,ssl,安全)