制作证书
命令制作用于SSL/TSL的证书
1、服务器端===>生成自签名证书**
keytool -genkeypair -keyalg RSA -keysize 2048 -keystore d:/server.jks -alias server -validity 365 -keypass 123456 -storepass 123456 -dname "CN=localhost" -ext san=IP:192.168.1.9
这段命令是使用Java的keytool工具生成一个RSA算法的密钥对,并将其保存在名为server.jks的密钥库文件中。以下是各个参数的解释:
- -genkeypair:生成密钥对的命令。
- -keyalg RSA:指定使用RSA算法生成密钥对。
- -keysize 2048:指定生成的密钥长度为2048位。
- -keystore d:/server.jks:指定保存生成的密钥对的密钥库文件路径为d:/server.jks。
- -alias server:指定生成的密钥对的别名为server。
- -validity 365:指定生成的证书的有效期为365天。
- -keypass 123456:指定生成的密钥对的密码为123456。
- -storepass 123456:指定密钥库文件的密码为123456。
- -dname “CN=localhost”:指定生成的证书的Distinguished Name(DN),包括Common Name(CN),这里设置为localhost。
- -ext san=IP:192.168.1.9:添加Subject Alternative Name(SAN)扩展,指定证书的主体为IP地址192.168.1.9。
通过这个命令,将生成一个包含RSA密钥对的密钥库文件,并且生成一个证书,该证书中包含了服务器的IP地址192.168.1.9作为主体。这个证书可以用于配置服务器端的SSL/TLS通信,以确保通信的安全性。
2、服务器端===>从服务器端证书秘钥库中导出Cer证书**
keytool -export -alias server -keystore d:/server.jks -storepass 123456 -file d:/server.cer
上面的命令使用keytool工具从server.jks keystore中导出server别名的证书,并保存为server.cer文件。以下是命令的详细说明:
- -export:指定要执行导出操作。
- -alias server:指定要导出的证书的别名为server。
- -keystore d:/server.jks:指定要导出证书的keystore文件路径为d:/server.jks。
- -storepass 123456:指定keystore的密码为123456。
- -file d:/server.cer:指定导出的证书保存的文件路径为d:/server.cer。
执行该命令后,会将server.jks keystore中server别名的证书导出为server.cer文件。这个导出的证书文件可以用于配置服务器端以进行SSL双向认证,或者用于其他需要验证证书的场景。请确保妥善保管导出的证书文件,以确保通信的安全性。
3、客户端==>生成自签名证书**
keytool -genkeypair -keyalg RSA -keysize 2048 -keystore d:/client.jks -alias client -validity 365 -keypass 123456 -storepass 123456 -dname "CN=localhost" -ext san=IP:192.168.1.9
这段命令与上一个命令类似,也是使用Java的keytool工具生成一个RSA算法的密钥对,并将其保存在名为client.jks的密钥库文件中。以下是各个参数的解释:
- -genkeypair:生成密钥对的命令。
- -keyalg RSA:指定使用RSA算法生成密钥对。
- -keysize 2048:指定生成的密钥长度为2048位。
- -keystore d:/client.jks:指定保存生成的密钥对的密钥库文件路径为d:/client.jks。
- -alias client:指定生成的密钥对的别名为client。
- -validity 365:指定生成的证书的有效期为365天。
- -keypass 123456:指定生成的密钥对的密码为123456。
- -storepass 123456:指定密钥库文件的密码为123456。
- -dname “CN=localhost”:指定生成的证书的Distinguished Name(DN),包括Common Name(CN),这里设置为localhost。
- -ext san=IP:192.168.1.9:添加Subject Alternative Name(SAN)扩展,指定证书的主体为IP地址192.168.1.9。
通过这个命令,将生成一个包含RSA密钥对的密钥库文件,并且生成一个证书,该证书中包含了客户端的IP地址192.168.1.9作为主体。这个证书可以用于配置客户端的SSL/TLS通信,以确保通信的安全性。
4、客户端==>从服务器端证书秘钥库中导出Cer证书**
keytool -export -alias client -keystore d:/client.jks -storepass 123456 -file d:/client.cer
上面的命令使用keytool工具从client.jks keystore中导出client别名的证书,并保存为client.cer文件。以下是命令的详细说明:
- -export:指定要执行导出操作。
- -alias client:指定要导出的证书的别名为client。
- -keystore d:/client.jks:指定要导出证书的keystore文件路径为d:/client.jks。
- -storepass 123456:指定keystore的密码为123456。
- -file d:/client.cer:指定导出的证书保存的文件路径为d:/client.cer。
执行该命令后,会将client.jks keystore中client别名的证书导出为client.cer文件。这个导出的证书文件可以用于配置客户端以进行SSL双向认证,或者用于其他需要验证证书的场景。请确保妥善保管导出的证书文件,以确保通信的安全性。
5、客户端==>将客户端证书导入到服务器端证书秘钥库**
keytool -import -trustcacerts -alias server -file d:/server.cer -keystore d:/client.jks -storepass 123456
上面的命令使用keytool工具将名为server.cer的服务器证书导入到client.jks证书库中。以下是命令的详细说明:
- -import:指定要执行导入操作。
- -trustcacerts:指定将证书视为受信任的CA证书。
- -alias server:指定要为导入证书指定的别名为server。
- -file d:/server.cer:指定要导入的证书文件路径为d:/server.cer。
- -keystore d:/client.jks:指定要导入证书的证书库文件路径为d:/client.jks。
- -storepass 123456:指定证书库的密码为123456。
执行该命令后,会将名为server.cer的服务器证书导入到client.jks证书库中,并分配别名为server。这样,客户端client就可以使用这个证书来验证服务器的身份。请确保导入的证书文件和密码的安全性,以确保通信的安全性。
6、服务器端==>将服务器端证书导入到客户端证书秘钥库**
keytool -import -trustcacerts -alias client -file d:/client.cer -keystore d:/server.jks -storepass 123456
在这个命令中,您使用keytool工具将名为client.cer的客户端证书导入到server.jks证书库中。以下是命令的详细说明:
- -import:指定要执行导入操作。
- -trustcacerts:指定将证书视为受信任的CA证书。
- -alias client:指定要为导入证书指定的别名为client。
- -file d:/client.cer:指定要导入的证书文件路径为d:/client.cer。
- -keystore d:/server.jks:指定要导入证书的证书库文件路径为d:/server.jks。
- -storepass 123456:指定证书库的密码为123456。
执行该命令后,会将名为client.cer的客户端证书导入到server.jks证书库中,并分配别名为client。这样,服务器端server就可以使用这个证书来验证客户端client的身份。请确保导入的证书文件和密码的安全性,以确保通信的安全性。
7、将客户端导出浏览器可安装的证书**
keytool -importkeystore -srckeystore d:/client.jks -destkeystore d:/client.p12 -srcstoretype JKS -deststoretype PKCS12 -srcstorepass 123456 -deststorepass 123456 -srckeypass 123456 -destkeypass 123456 -srcalias client -destalias client -noprompt
在这个命令中,您使用keytool工具将名为client.jks的Java密钥库(JKS)转换为名为client.p12的PKCS12格式的密钥库。以下是命令的详细说明:
- -importkeystore:指定要执行密钥库转换操作。
- -srckeystore client.jks:指定要转换的源密钥库文件路径为client.jks。
- -destkeystore client.p12:指定要生成的目标密钥库文件路径为client.p12。
- -srcstoretype JKS:指定源密钥库的类型为JKS。
- -deststoretype PKCS12:指定目标密钥库的类型为PKCS12。
- -srcstorepass 123456:指定源密钥库的密码为123456。
- -deststorepass 123456:指定目标密钥库的密码为123456。
- -srckeypass 123456:指定源密钥库中密钥的密码为123456。
- -destkeypass 123456:指定目标密钥库中密钥的密码为123456。
- -srcalias client:指定要转换的源密钥库中的别名为client。
- -destalias client:指定在目标密钥库中为转换后的别名为client。
- -noprompt:禁止提示用户输入任何信息,以便自动执行转换操作。
执行该命令后,将会将client.jks的密钥库转换为client.p12的PKCS12格式的密钥库,并分配别名为client。请确保密码的安全性,以确保密钥库的安全性。
8、将服务端导出浏览器可安装的证书**
keytool -importkeystore -srckeystore d:/server.jks -destkeystore d:/server.p12 -srcstoretype JKS -deststoretype PKCS12 -srcstorepass 123456 -deststorepass 123456 -srckeypass 123456 -destkeypass 123456 -srcalias server -destalias server -noprompt
在这个命令中,您使用keytool工具将名为server.jks的Java密钥库(JKS)转换为名为server.p12的PKCS12格式的密钥库。以下是命令的详细说明:
- -importkeystore:指定要执行密钥库转换操作。
- -srckeystore server.jks:指定要转换的源密钥库文件路径为server.jks。
- -destkeystore server.p12:指定要生成的目标密钥库文件路径为server.p12。
- -srcstoretype JKS:指定源密钥库的类型为JKS。
- -deststoretype PKCS12:指定目标密钥库的类型为PKCS12。
- -srcstorepass 123456:指定源密钥库的密码为123456。
- -deststorepass 123456:指定目标密钥库的密码为123456。
- -srckeypass 123456:指定源密钥库中密钥的密码为123456。
- -destkeypass 123456:指定目标密钥库中密钥的密码为123456。
- -srcalias server:指定要转换的源密钥库中的别名为server。
- -destalias server:指定在目标密钥库中为转换后的别名为server。
- -noprompt:禁止提示用户输入任何信息,以便自动执行转换操作。
执行该命令后,将会将server.jks的密钥库转换为server.p12的PKCS12格式的密钥库,并分配别名为server。请确保密码的安全性,以确保密钥库的安全性。
查看颁发证书
此步只是为了检查证书的内容,jks的信任库中是否存在对方秘钥。
keytool -list -v -keystore d:/server.jks -storepass 123456
keytool -list -v -keystore d:/client.jks -storepass 123456
最后生成的文件:
springboot项目配置
项目application.yml文件配置
服务端:
server:
port: 2222
ssl:
key-store: D://server.jks
key-store-password: 123456
key-alias: server
trust-store: D://server.jks
trust-store-password: 123456
#是否需要进行认证
client-auth: need
客户端:
server:
port: 3333
ssl:
key-store: D://client.jks
key-store-password: 123456
key-alias: server
trust-store: D://client.jks
trust-store-password: 123456
#是否需要进行认证
client-auth: need
解释:
- server.port: 2222:指定了应用的服务器端口号为2222。
- server.ssl.key-store: classpath:server.jks:指定了SSL连接使用的服务器端证书存储路径为classpath:server.jks,即在classpath下的server.jks文件。
- server.ssl.key-store-password: 123456:指定了服务器端证书存储文件的密码为123456。
- server.ssl.key-alias: server:指定了服务器端证书的别名为server。
- server.ssl.trust-store: classpath:server.jks:指定了SSL连接使用的客户端信任库路径为classpath:server.jks,即在classpath下的server.jks文件。
- server.ssl.trust-store-password: 123456:指定了客户端信任库文件的密码为123456。
- server.ssl.client-auth: need:指定了客户端需要进行双向认证,即客户端需要提供证书进行身份验证。
controller编写
服务端:
@RestController("/")
public class HelloWorld {
@RequestMapping("/")
public String hello(){
return "这是服务端后台:你好世界!";
}
@Autowired
RestTemplate restTemplate;
@GetMapping("/test")
public String sendRequest() {
String url = "https://192.168.1.9:3333"; // 替换为接收请求的项目的API接口地址
String forObject = restTemplate.getForObject(url, String.class);
return "服务端访问客户端》》》"+forObject;
}
}
客户端:
@RestController("/")
public class HelloWorld {
@RequestMapping("/")
public String hello(){
return "这是客户端后台:你好世界!";
}
@Autowired
RestTemplate restTemplate;
@GetMapping("/test")
public String sendRequest() {
String url = "https://192.168.1.9:2222"; // 替换为接收请求的项目的API接口地址
String forObject = restTemplate.getForObject(url, String.class);
return "客户端访问服务端》》》"+forObject;
}
}
浏览器测试
先启动刚配置好的springboot服务**
在浏览器访问服务端https://192.168.1.9:2222 浏览器提示不接受您的登录证书,或者您可能没有提供登录证书。
在浏览器中点击设置——》搜索SSL——》进入安全——》点击管理您设备上的 HTTPS/SSL 证书
点击导入——》筛选个人信息交换——》选择client.p12文件——》打开
下一步输入证书密码123456——》默认下一步即可添加成功 如图:
重新刷新浏览器https://192.168.1.9:2222——选择确认证书即可成功访问
在浏览器访问客户端是一样的操作https://192.168.1.9:3333 浏览器提示不接受您的登录证书,或者您可能没有提供登录证书将server.p12文件证书导入即可。
main方法测试
下面这两段代码是用来测试使用,不加入springboot项目中,仅测试使用证书与客户端、服务端是否可以握手成功。
客户端访问服务端 使用客户端证书
public static void main(String[] args) throws Exception{
KeyStore keyStore = KeyStore.getInstance("JKS");
keyStore.load(new FileInputStream(new File("D://client.jks")), "123456".toCharArray());
KeyStore trustStore = KeyStore.getInstance("JKS");
trustStore.load(new FileInputStream(new File("D://client.jks")), "123456".toCharArray());
SSLContext sslContext = SSLContextBuilder
.create()
.loadKeyMaterial(keyStore, "123456".toCharArray())
.loadTrustMaterial(trustStore, null)
.build();
CloseableHttpClient httpClient = HttpClients.custom()
.setSSLContext(sslContext)
.setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE)//禁用主体名》当制作证书的主体名是随便写的,握手时一定会报报主体名问题,此时可以先禁用主体名。
.build();
ClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(httpClient);
RestTemplate restTemplate= new RestTemplate(requestFactory);
String forObject = restTemplate.getForObject("https://192.168.1.9:2222", String.class);
System.out.println("测试访问》》》"+forObject);;
}
服务端访问客户端 使用服务端证书
public static void main(String[] args) throws Exception{
KeyStore keyStore = KeyStore.getInstance("JKS");
keyStore.load(new FileInputStream(new File("D://server.jks")), "123456".toCharArray());
KeyStore trustStore = KeyStore.getInstance("JKS");
trustStore.load(new FileInputStream(new File("D://server.jks")), "123456".toCharArray());
SSLContext sslContext = SSLContextBuilder
.create()
.loadKeyMaterial(keyStore, "123456".toCharArray())
.loadTrustMaterial(trustStore, null)
.build();
CloseableHttpClient httpClient = HttpClients.custom()
.setSSLContext(sslContext)
.setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE)//禁用主体名》当制作证书的主体名是随便写的,握手时一定会报报主体名问题,此时可以先禁用主体名。
.build();
ClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(httpClient);
RestTemplate restTemplate= new RestTemplate(requestFactory);
String forObject = restTemplate.getForObject("https://192.168.1.9:3333", String.class);
System.out.println("测试访问》》》"+forObject);;
}
到了这一步说明证书配置没有问题,双向认证也是通的。
springboot项目间SSL双重认证相互访问
springboot项目之间双向认证的互相通信主要在请求时有所变化:
客户端访问服务端的RestTemplate
@Configuration
public class RestConfig {
@Bean
public RestTemplate restTemplate() throws Exception {
KeyStore keyStore = KeyStore.getInstance("JKS");
keyStore.load(new FileInputStream(new File("D://client.jks")), "123456".toCharArray());
KeyStore trustStore = KeyStore.getInstance("JKS");
trustStore.load(new FileInputStream(new File("D://client.jks")), "123456".toCharArray());
SSLContext sslContext = SSLContextBuilder
.create()
.loadKeyMaterial(keyStore, "123456".toCharArray())
.loadTrustMaterial(trustStore, null)
.build();
CloseableHttpClient httpClient = HttpClients.custom()
.setSSLContext(sslContext)
.setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE)//禁用主体名》当制作证书的主体名是随便写的,握手时一定会报报主体名问题,此时可以先禁用主体名。
.build();
ClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(httpClient);
return new RestTemplate(requestFactory);
}
}
服务端访问客户端的RestTemplate
@Configuration
public class RestConfig {
@Bean
public RestTemplate restTemplate() throws Exception {
KeyStore keyStore = KeyStore.getInstance("JKS");
keyStore.load(new FileInputStream(new File("D://server.jks")), "123456".toCharArray());
KeyStore trustStore = KeyStore.getInstance("JKS");
trustStore.load(new FileInputStream(new File("D://server.jks")), "123456".toCharArray());
SSLContext sslContext = SSLContextBuilder
.create()
.loadKeyMaterial(keyStore, "123456".toCharArray())
.loadTrustMaterial(trustStore, null)
.build();
CloseableHttpClient httpClient = HttpClients.custom()
.setSSLContext(sslContext)
.setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE)//禁用主体名》当制作证书的主体名是随便写的,握手时一定会报报主体名问题,此时可以先禁用主体名。
.build();
ClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(httpClient);
return new RestTemplate(requestFactory);
}
}
验证是否正确通信
浏览器中访问https://192.168.1.9:2222/test查看结果:
浏览器中访问https://192.168.1.9:3333/test查看结果:
按照自己想法来 使用RestTemplate正常去访问对方的服务即可。文章来源:https://www.toymoban.com/news/detail-842007.html
源代码已上传SCDN:
https://download.csdn.net/download/YnagLei/88914176文章来源地址https://www.toymoban.com/news/detail-842007.html
到了这里,关于springboot项目开启ssl双向认证且实现相互访问通信浏览器访问通信的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!