Java SSL Socket
Java SSLSocket 服务端
单向认证
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.security.KeyStore;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLServerSocket;
import javax.net.ssl.TrustManagerFactory;
public class SSLServer {
private SSLServerSocket sslServerSocket;
public static void main(String[] args) throws Exception {
SSLServer server = new SSLServer();
server.init();
System.out.println("SSLServer initialized.");
server.process();
}
//服务器端将要使用到server.keystore和ca-trust.keystore
public void init() throws Exception {
int port = 1234;
String keystorePath = "/home/user/CA/certs/server.keystore";
String trustKeystorePath = "/home/user/CA/certs/ca-trust.keystore";
String keystorePassword = "abc123_";
SSLContext context = SSLContext.getInstance("SSL");
//客户端证书库
KeyStore keystore = KeyStore.getInstance("pkcs12");
FileInputStream keystoreFis = new FileInputStream(keystorePath);
keystore.load(keystoreFis, keystorePassword.toCharArray());
//信任证书库
KeyStore trustKeystore = KeyStore.getInstance("jks");
FileInputStream trustKeystoreFis = new FileInputStream(trustKeystorePath);
trustKeystore.load(trustKeystoreFis, keystorePassword.toCharArray());
//密钥库
KeyManagerFactory kmf = KeyManagerFactory.getInstance("sunx509");
kmf.init(keystore, keystorePassword.toCharArray());
//信任库
TrustManagerFactory tmf = TrustManagerFactory.getInstance("sunx509");
tmf.init(trustKeystore);
//初始化SSL上下文
context.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
//初始化SSLSocket
sslServerSocket = (SSLServerSocket)context.getServerSocketFactory().createServerSocket(port);
//设置这个SSLServerSocket需要授权的客户端访问
sslServerSocket.setNeedClientAuth(true);
}
public void process() throws Exception {
String bye = "Bye!";
byte[] buffer = new byte[50];
while(true) {
Socket socket = sslServerSocket.accept();
InputStream in = socket.getInputStream();
in.read(buffer);
System.out.println("Received: " + new String(buffer));
OutputStream out = socket.getOutputStream();
out.write(bye.getBytes());
out.flush();
}
}
}Java SSLSocket 客户端
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.KeyStore;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.TrustManagerFactory;
public class SSLClient {
private SSLSocket sslSocket;
public static void main(String[] args) throws Exception {
SSLClient client = new SSLClient();
client.init();
System.out.println("SSLClient initialized.");
client.process();
}
//客户端将要使用到client.keystore和ca-trust.keystore
public void init() throws Exception {
String host = "127.0.0.1";
int port = 1234;
String keystorePath = "/home/user/CA/certs/client.keystore";
String trustKeystorePath = "/home/user/CA/certs/ca-trust.keystore";
String keystorePassword = "abc123_";
SSLContext context = SSLContext.getInstance("SSL");
//客户端证书库
KeyStore clientKeystore = KeyStore.getInstance("pkcs12");
FileInputStream keystoreFis = new FileInputStream(keystorePath);
clientKeystore.load(keystoreFis, keystorePassword.toCharArray());
//信任证书库
KeyStore trustKeystore = KeyStore.getInstance("jks");
FileInputStream trustKeystoreFis = new FileInputStream(trustKeystorePath);
trustKeystore.load(trustKeystoreFis, keystorePassword.toCharArray());
//密钥库
KeyManagerFactory kmf = KeyManagerFactory.getInstance("sunx509");
kmf.init(clientKeystore, keystorePassword.toCharArray());
//信任库
TrustManagerFactory tmf = TrustManagerFactory.getInstance("sunx509");
tmf.init(trustKeystore);
//初始化SSL上下文
context.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
sslSocket = (SSLSocket)context.getSocketFactory().createSocket(host, port);
}
public void process() throws Exception {
//往SSLSocket中写入数据
String hello = "hello boy!";
OutputStream out = sslSocket.getOutputStream();
out.write(hello.getBytes(), 0, hello.getBytes().length);
out.flush();
//从SSLSocket中读取数据
InputStream in = sslSocket.getInputStream();
byte[] buffer = new byte[50];
in.read(buffer);
System.out.println(new String(buffer));
}
}
Java RSA 公&私钥加密
参考: 如何使用微信支付公钥加密敏感字段- https://pay.weixin.qq.com/doc/v3/merchant/4013053257
公钥加密
public static String rsaDecryptOAEP(String ciphertext, PrivateKey privateKey)
throws BadPaddingException, IOException {
try {
Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-1AndMGF1Padding");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] data = Base64.getDecoder().decode(ciphertext);
return new String(cipher.doFinal(data), "utf-8");
} catch (NoSuchPaddingException | NoSuchAlgorithmException e) {
throw new RuntimeException("当前Java环境不支持RSA v1.5/OAEP", e);
} catch (InvalidKeyException e) {
throw new IllegalArgumentException("无效的私钥", e);
} catch (BadPaddingException | IllegalBlockSizeException e) {
throw new BadPaddingException("解密失败");
}
}
私钥解密
public static String rsaDecryptOAEP(String ciphertext, PrivateKey privateKey)
throws BadPaddingException, IOException {
try {
Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-1AndMGF1Padding");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] data = Base64.getDecoder().decode(ciphertext);
return new String(cipher.doFinal(data), "utf-8");
} catch (NoSuchPaddingException | NoSuchAlgorithmException e) {
throw new RuntimeException("当前Java环境不支持RSA v1.5/OAEP", e);
} catch (InvalidKeyException e) {
throw new IllegalArgumentException("无效的私钥", e);
} catch (BadPaddingException | IllegalBlockSizeException e) {
throw new BadPaddingException("解密失败");
}
}