//生成.jks秘钥
keytool -genkey -keystore e:\file\a\server_ks.jks -storepass server_password -keyalg RSA -keypass server_password
C:\Program Files\Java\jdk1.8.0_221\bin>keytool -genkey -keystore e:\file\a\server_ks.jks -storepass server_password -keyalg RSA -keypass server_password
您的名字与姓氏是什么?
[Unknown]: panghu
您的组织单位名称是什么?
[Unknown]: test
您的组织名称是什么?
[Unknown]: test
您所在的城市或区域名称是什么?
[Unknown]: shenzhen
您所在的省/市/自治区名称是什么?
[Unknown]: guangdong
该单位的双字母国家/地区代码是什么?
[Unknown]: 86
CN=panghu, OU=test, O=test, L=shenzhen, ST=guangdong, C=86是否正确?
[否]: y
//生成证书
keytool -export -keystore e:\file\a\server_ks.jks -storepass server_password -file e:\file\a\server.cer
C:\Program Files\Java\jdk1.8.0_221\bin>keytool -export -keystore e:\file\a\server_ks.jks -storepass server_password -file e:\file\a\server.cer
存储在文件 <e:\file\a\server.cer> 中的证书
单向HTTPS验证
public static void main(String[] args) {
new Thread(new ServerOne()).start();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(new ClientOne()).start();
}
public static class ServerOne implements Runnable {
//SSL协议版本
private static final String TLS = "TLSv1.2";
//KeyStore的类型
private static final String PROVIDER = "SunX509";
private static final String STORE_TYPE = "JKS";
//秘钥的路径
private static final String KEY_STORE_NAME = "e:\\file\\a\\server_ks.jks";
//Server的端口
private static final int DEFAULT_PORT = 8090; //自定义端口
//秘钥的密码
private static final String SERVER_KEY_STORE_PASSWORD = "server_password"; //秘钥的密码
@Override
public void run() {
try {
//获取SSLContext
SSLContext sslContext = SSLContext.getInstance(TLS);
//生成秘钥的manager
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(PROVIDER);
//加载秘钥
KeyStore keyStoreOne = KeyStore.getInstance(STORE_TYPE);
keyStoreOne.load(new FileInputStream(KEY_STORE_NAME), SERVER_KEY_STORE_PASSWORD.toCharArray());
//秘钥初始化
keyManagerFactory.init(keyStoreOne, SERVER_KEY_STORE_PASSWORD.toCharArray());
//初始化SSLContext
sslContext.init(keyManagerFactory.getKeyManagers(), null, null);
//获取SSLContext的SocketFactory
SSLServerSocket sslServerSocket =
(SSLServerSocket) sslContext.getServerSocketFactory()
.createServerSocket(DEFAULT_PORT);
//是否开启双向验证
sslServerSocket.setNeedClientAuth(false);
System.out.println("服务器已开启,等待连接 .....");
Socket accept = sslServerSocket.accept();
System.out.println("客户端 : " + accept.getInetAddress().getHostAddress());
InputStream inputStream = accept.getInputStream();
byte[] bytes = new byte[1024];
int len = 0;
while ((len = inputStream.read(bytes)) != -1) {
System.out.println("服务器收到数据 : " + new String(bytes, 0, len));
}
inputStream.close();
accept.close();
sslServerSocket.close();
System.out.println("服务器关闭");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (KeyStoreException e) {
e.printStackTrace();
} catch (CertificateException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (UnrecoverableKeyException e) {
e.printStackTrace();
} catch (KeyManagementException e) {
e.printStackTrace();
}
}
}
public static class ClientOne implements Runnable {
private static final String TLS = "TLSv1.2";
private static final String PROVIDER = "SunX509";
private static final String STORE_TYPE = "JKS";
private static final String TRUST_STORE_NAME = "e:\\file\\a\\server.cer";
@Override
public void run() {
try {
SSLContext sslContext = SSLContext.getInstance(TLS);
//生成信任证书Manager,默认系统会信任CA机构颁发的证书,自定的证书需要手动的加载
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(PROVIDER);
KeyStore keyStore = KeyStore.getInstance(STORE_TYPE);
keyStore.load(null);
//这种方式加载需要知道证书的密码
//keyStore.load(new FileInputStream(TRUST_STORE_NAME),"password".toCharArray());
//生成验证工厂
CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
//生成别名(可以随便填写)
String certificateAlias = Integer.toString(0);
//加载证书
keyStore.setCertificateEntry(
certificateAlias,
certificateFactory.generateCertificate(
new FileInputStream(TRUST_STORE_NAME)));//拷贝好的证书
//初始化
trustManagerFactory.init(keyStore);
//初始化
sslContext.init(null, trustManagerFactory.getTrustManagers(), null);
SSLSocket socket = (SSLSocket) sslContext.getSocketFactory().createSocket("192.168.0.10", 8090);
socket.startHandshake();
OutputStream outputStream = socket.getOutputStream();
outputStream.write("这是SSL测试".getBytes());
outputStream.flush();
outputStream.close();
socket.close();
System.out.println("客户端关闭");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (KeyStoreException e) {
e.printStackTrace();
} catch (CertificateException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (KeyManagementException e) {
e.printStackTrace();
}
}
}
输出:
服务器已开启,等待连接 .....
客户端 : 192.168.0.10
服务器收到数据 : 这是SSL测试
客户端关闭
服务器关闭
双向HTTPS验证
//生成client端的秘钥和证书文件
C:\Program Files\Java\jdk1.8.0_221\bin>keytool -genkey -keystore e:\file\a\client_ks.jks -storepass client_password -keyalg RSA -keypass client_password
您的名字与姓氏是什么?
[Unknown]: panghu
您的组织单位名称是什么?
[Unknown]: test
您的组织名称是什么?
[Unknown]: test
您所在的城市或区域名称是什么?
[Unknown]: shenzhen
您所在的省/市/自治区名称是什么?
[Unknown]: guangdong
该单位的双字母国家/地区代码是什么?
[Unknown]: 86
CN=panghu, OU=test, O=test, L=shenzhen, ST=guangdong, C=86是否正确?
[否]: y
C:\Program Files\Java\jdk1.8.0_221\bin>keytool -export -keystore e:\file\a\client_ks.jks -storepass client_password -file e:\file\a\client.cer
存储在文件 <e:\file\a\client.cer> 中的证书
//把server.cer证书添加到serverTrust_ks.jks文件中
C:\Program Files\Java\jdk1.8.0_221\bin>keytool -import -keystore e:\file\a\serverTrust_ks.jks -storepass client -file e:\file\a\server.cer
所有者: CN=panghu, OU=test, O=test, L=shenzhen, ST=guangdong, C=86
发布者: CN=panghu, OU=test, O=test, L=shenzhen, ST=guangdong, C=86
序列号: 5d765707
有效期为 Mon Sep 23 18:33:19 CST 2019 至 Sun Dec 22 18:33:19 CST 2019
证书指纹:
MD5: 9E:9D:33:A2:3C:A7:E5:61:F1:41:A7:DE:DF:66:45:56
SHA1: E8:D9:F9:F8:03:60:F0:A9:34:D5:1C:99:86:22:AA:B4:B3:61:66:B5
SHA256: 6C:82:5F:9F:31:C3:32:EC:62:CE:6C:59:C7:13:C1:6A:95:5B:4C:55:63:D0:A1:CE:7A:4B:1A:ED:9A:D0:CF:20
签名算法名称: SHA256withRSA
主体公共密钥算法: 2048 位 RSA 密钥
版本: 3
扩展:
#1: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: CC 01 50 17 30 85 97 C8 DC 17 F5 59 52 DE 5F 90 ..P.0......YR._.
0010: 4A 47 13 E4 JG..
]
]
是否信任此证书? [否]: y
证书已添加到密钥库中
// 把client端证书添加到clientTrust_ks.jks文件中
C:\Program Files\Java\jdk1.8.0_221\bin>keytool -import -keystore e:\file\a\clientTrust_ks.jks -storepass server -file e:\file\a\client.cer
所有者: CN=panghu, OU=test, O=test, L=shenzhen, ST=guangdong, C=86
发布者: CN=panghu, OU=test, O=test, L=shenzhen, ST=guangdong, C=86
序列号: 2a332242
有效期为 Mon Sep 23 19:06:09 CST 2019 至 Sun Dec 22 19:06:09 CST 2019
证书指纹:
MD5: A2:E1:C3:1B:8B:F1:78:C4:7D:EE:65:72:DB:B9:23:01
SHA1: 42:27:6B:B2:10:5F:80:75:D7:F5:D5:33:01:25:08:8C:33:C6:B4:76
SHA256: BB:A9:6C:44:2D:A2:30:6F:01:71:42:6E:6B:3F:19:5C:77:8A:05:79:9F:03:0E:42:E8:2E:A2:3C:47:E9:F6:E0
签名算法名称: SHA256withRSA
主体公共密钥算法: 2048 位 RSA 密钥
版本: 3
扩展:
#1: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: 16 AB 67 DE 94 D4 8C 05 56 88 91 72 98 9A D4 FD ..g.....V..r....
0010: 96 16 C4 F3 ....
]
]
是否信任此证书? [否]: y
证书已添加到密钥库中
new Thread(new Server()).start();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(new Client()).start();
public static class Server implements Runnable {
private static final String TLS = "TLSv1.2";
private static final String PROVIDER = "SunX509";
private static final String STORE_TYPE = "JKS";
private static final String KEY_STORE_NAME = "e:\\file\\a\\server_ks.jks";
private static final String TRUST_STORE_NAME = "e:\\file\\a\\clientTrust_ks.jks";
private static final int DEFAULT_PORT = 8090; //自定义端口
private static final String SERVER_KEY_STORE_PASSWORD = "server_password"; //密码
private static final String SERVER_TRUST_KEY_STORE_PASSWORD = "server";//密码
@Override
public void run() {
try {
SSLContext sslContext = SSLContext.getInstance(TLS);
//加载server端的秘钥
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(PROVIDER);
//加载信任的证书
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(PROVIDER);
KeyStore keyStoreOne = KeyStore.getInstance(STORE_TYPE);
KeyStore keyStoreTwo = KeyStore.getInstance(STORE_TYPE);
keyStoreOne.load(new FileInputStream(KEY_STORE_NAME), SERVER_KEY_STORE_PASSWORD.toCharArray());
keyStoreTwo.load(new FileInputStream(TRUST_STORE_NAME), SERVER_TRUST_KEY_STORE_PASSWORD.toCharArray());
keyManagerFactory.init(keyStoreOne, SERVER_KEY_STORE_PASSWORD.toCharArray());
trustManagerFactory.init(keyStoreTwo);
sslContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), null);
SSLServerSocket sslServerSocket = (SSLServerSocket) sslContext.getServerSocketFactory().createServerSocket(DEFAULT_PORT);
// 开启双向验证
sslServerSocket.setNeedClientAuth(true);
System.out.println("服务器已开启,等待连接 .....");
Socket accept = sslServerSocket.accept();
System.out.println("客户端 : " + accept.getInetAddress().getHostAddress());
InputStream inputStream = accept.getInputStream();
byte[] bytes = new byte[1024];
int len = 0;
while ((len = inputStream.read(bytes)) != -1) {
System.out.println("服务器收到数据 : " + new String(bytes, 0, len));
}
inputStream.close();
accept.close();
sslServerSocket.close();
System.out.println("服务器关闭");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (KeyStoreException e) {
e.printStackTrace();
} catch (CertificateException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (UnrecoverableKeyException e) {
e.printStackTrace();
} catch (KeyManagementException e) {
e.printStackTrace();
}
}
}
public static class Client implements Runnable {
private static final String TLS = "TLSv1.2";
private static final String PROVIDER = "SunX509";
private static final String STORE_TYPE = "JKS";
private static final String KEY_STORE_NAME = "e:\\file\\a\\client_ks.jks";
private static final String TRUST_STORE_NAME = "e:\\file\\a\\serverTrust_ks.jks";
private static final String CLIENT_KEY_STORE_PASSWORD = "client_password"; //密码
private static final String CLIENT_TRUST_KEY_STORE_PASSWORD = "client";//密码
@Override
public void run() {
try {
SSLContext sslContext = SSLContext.getInstance(TLS);
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(PROVIDER);
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(PROVIDER);
KeyStore keyStoreOne = KeyStore.getInstance(STORE_TYPE);
KeyStore keyStoreTwo = KeyStore.getInstance(STORE_TYPE);
//加载client端的秘钥
keyStoreOne.load(new FileInputStream(KEY_STORE_NAME), CLIENT_KEY_STORE_PASSWORD.toCharArray());
//信任证书
keyStoreTwo.load(new FileInputStream(TRUST_STORE_NAME), CLIENT_TRUST_KEY_STORE_PASSWORD.toCharArray());
keyManagerFactory.init(keyStoreOne, CLIENT_KEY_STORE_PASSWORD.toCharArray());
trustManagerFactory.init(keyStoreTwo);
sslContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), null);
SSLSocket socket = (SSLSocket) sslContext.getSocketFactory().createSocket("192.168.0.10", 8090);
socket.startHandshake();
OutputStream outputStream = socket.getOutputStream();
outputStream.write("这是SSL测试".getBytes());
outputStream.flush();
outputStream.close();
socket.close();
System.out.println("客户端关闭");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (KeyStoreException e) {
e.printStackTrace();
} catch (CertificateException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (UnrecoverableKeyException e) {
e.printStackTrace();
} catch (KeyManagementException e) {
e.printStackTrace();
}
}
}
网友评论