OpenSSL 证书
目录
证书标准
编码格式
PEM: Privacy Enhanced Mail
DER: Distinguished Encoding Rules
编码转换:
文件扩展名
自签证书
签发根证书
生成CA私钥
生成CA申请文件
签发根证书
导出Java的CA证书
签发服务端证书
签发客户端证书
证书标准
X.509 数字证书标准,定义证书文件的结构和内容。
证数结构图:
编码格式
证书的编码格式:一般包括 PEM 和 DER 两种。
PEM: Privacy Enhanced Mail
DER: Distinguished Encoding Rules
编码转换:
PEM转DER
openssl x509 -in xxx.pem -outform der -out xxx.der
DER转PEM
openssl x509 -in xxx.der -inform der -outform pem -out xxx.pem
文件扩展名
自签证书
签发根证书
生成CA私钥
//生成CA私钥:
# openssl genrsa -des3 -out cakey.pem 2048
输入密码:Honeywell@654321// 查看CA私钥
# openssl rsa -in cakey.pem -text
生成CA申请文件
//根据私钥生成CA申请文件:
# openssl req -new -key cakey.pem -out ca.csr -subj "/C=CN/O=Honeywell/CN=WCS Project(rabbitmq)"//查看CA申请文件
# openssl req -noout -text -in ca.csr
签发根证书
//签发根证书:
# openssl x509 -req -days 3650 -sha1 -extfile /etc/pki/tls/openssl.cnf -extensions v3_ca -signkey cakey.pem -in ca.csr -out ca.cer// 查看证书
# openssl x509 -in ca.cer -text -noout
导出p12的CA证书
openssl pkcs12 -export -clcerts -in ca.cer -inkey cakey.pem -out ca.p12
导出JKS的CA证书
//导出服务端java程序可用的CA证书:
keytool -import -v -trustcacerts -storepass Honeywell@654321 -alias root -file ca.cer -keystore ca.jks
签发服务端证书
//服务端私钥
openssl genrsa -des3 -out server-key.pem 2048// 查看私钥
openssl rsa -in server-key.pem -text//服务端申请文件
openssl req -new -key server-key.pem -out server.csr -subj "/C=CN/O=Honeywell/CN=WCS Project(rabbitmq)"//使用根证书签发服务端证书
openssl x509 -req -days 3650 -sha1 -extfile /etc/pki/tls/openssl.cnf -extensions v3_req -CA ca.cer -CAkey cakey.pem -CAserial ca.srl -CAcreateserial -in server.csr -out server.cer//导出服务端p12证书:
openssl pkcs12 -export -clcerts -inkey server-key.pem -in server.cer -out server.p12//导出服务端java程序可用的JKS证书
keytool -import -v -trustcacerts -storepass Honeywell@654321 -alias server -file ca.cer -keystore server.jks
签发客户端证书
//私钥
openssl genrsa -des3 -out client-key.pem 2048
// 查看私钥
openssl rsa -in client-key.pem -text//客户端申请文件:
openssl req -new -key client-key.pem -out client.csr -subj "/C=CN/O=Honeywell/CN=WCS Project(rabbitmq)"
//查看申请文件
openssl req -text -noout -verify -in client.csr//使用根证书签发客户端证书:
openssl x509 -req -days 3650 -sha256 -extfile /etc/pki/tls/openssl.cnf -extensions v3_req -CA ca.cer -CAkey cakey.pem -CAserial ca.srl -in client.csr -out client.cer
//查看证书
openssl x509 -in client.cer -text -noout导出客户端证书:
openssl pkcs12 -export -clcerts -name wcsclient -inkey client-key.pem -in client.cer -out client.p12
// 查看p12证书
openssl pkcs12 -info -in client.p12//p12导入至keystore
keytool -import -v -trustcacerts -storepass Honeywell@654321 -alias client -file client.cer -keystore client.jks//查看keystore
keytool -v -list -keystore client.jks
合并证书
合并server.crt和ca.crt
-----BEGIN CERTIFICATE-----...ca.crt的内容-----END CERTIFICATE----------BEGIN CERTIFICATE-----...server.crt的内容-----END CERTIFICATE-----
转换为pkcs12格式
openssl pkcs12 -export -clcerts -in server.crt -inkey server.key -out server.p12
转换为jks格式
keytool -importkeystore -srckeystore server.p12 -destkeystore server.jks -srcstoretype pkcs12 -deststoretype jks
验证证书
keytool -list -v -keystore server.jks
KeyStore
KeyStore是一个存储库,可用于存储一系列密钥、密钥对或证书。
KeyStore的实现方式:JKS(Java Key Store)、PKCS12、JCEKS
JKS: 可以存储密钥对、证书,不能存储密钥。
PKCS12: 可以存储密钥对、证书、密钥。
JCEKS: 可以存储密钥对、证书、密钥。
keytool
keytool是JDK的Keystore管理工具。
JAVA代码
服务端:
package com.xxx.yyy.common.socket.utils;import cn.hutool.json.JSONUtil;
import com.xxx.yyy.common.socket.config.SocketServerTLSConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;import javax.net.ssl.*;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.*;
import java.security.cert.CertificateException;/*** keystore用于存放自己的密钥和公钥,* truststore用于存放所有需要信任方的公钥* SSLContext:SSLContext类可以创建SSLSocket实例,在这个类中配置自己的证书和自己所信任的证书。* KeyManagerFactory:加载自己的证书文件,并且生成KeyManager[]数据,配置到SSLContext。* TrustManagerFactory:加载自己信任的客户端证书,双向认证的时候配置自己信任哪些服务端证书。* KeyStore:加载证书的类。* TrustManager[]:信任的证书信任的Manager数组。* Manager[]:自己的证书的Manager数组。** @author H443745*/
public class SslSocketServerUtil {private static final Logger logger = LoggerFactory.getLogger(SslSocketServerUtil.class);private static final String PROTOCOL = "TLSv1.2";public static final String KEYSTORE_TYPE = "JKS";//KeyStore的类型private static final String PROVIDER = "SunX509";private SslSocketServerUtil() {}/*** 创建服务端socket** @param tlsConfig* @return* @throws Exception*/public static SSLServerSocket createSslServerSocket(SocketServerTLSConfig tlsConfig) throws IOException {SSLContext sslContext = createContext(tlsConfig);if (sslContext == null) {return null;}SSLServerSocketFactory serverSocketFactory = sslContext.getServerSocketFactory();// 绑定服务端口SSLServerSocket serverSocket = (SSLServerSocket) serverSocketFactory.createServerSocket(tlsConfig.getPort());// 设置加密算法套件String[] supported = serverSocketFactory.getSupportedCipherSuites();serverSocket.setEnabledCipherSuites(supported);logger.info("服务端可支持的加密算法套件有:{}", supported);//设置这个SSLServerSocket需要授权的客户端访问, 是否开启双向验证serverSocket.setNeedClientAuth(tlsConfig.isServerModeEnabled());return serverSocket;}/*** 创建上下文环境,主要用于保存安全通信的基本信息,如协议版本、证书管理方式** @param tlsConfig* @return* @throws Exception*/public static SSLContext createContext(SocketServerTLSConfig tlsConfig) {logger.info("开始服务端创建sslContext上下文......");//服务端证书库KeyStore serverKeystore = null;FileInputStream fileInputStream = null;KeyStore trustKeystore = null;FileInputStream trustFileInputStream = null;try {serverKeystore = KeyStore.getInstance(KEYSTORE_TYPE);fileInputStream = new FileInputStream(tlsConfig.getServerKeystorePath());serverKeystore.load(fileInputStream, tlsConfig.getServerKeystorePassword().toCharArray());/// KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());//生成秘钥的managerKeyManagerFactory kmf = KeyManagerFactory.getInstance(PROVIDER);// 管理本端 的密钥(发送本端的证书用于对方认证我的身份)logger.info(KeyManagerFactory.getDefaultAlgorithm());//秘钥初始化kmf.init(serverKeystore, tlsConfig.getServerKeystorePassword().toCharArray());SSLContext sslContext = SSLContext.getInstance(PROTOCOL);logger.info("缺省安全套接字使用的协议:{} ", sslContext.getProtocol());//是否双向验证boolean serverModeEnabled = tlsConfig.isServerModeEnabled();if(serverModeEnabled){// 管理对端证书的信任证书,用于认证对方的身份trustKeystore = KeyStore.getInstance(KEYSTORE_TYPE);trustFileInputStream = new FileInputStream(tlsConfig.getServerTrustKeystorePath());trustKeystore.load(trustFileInputStream, tlsConfig.getServerTrustKeystorePassword().toCharArray());// 信任库TrustManagerFactory tmf = TrustManagerFactory.getInstance(PROVIDER);// 信任证书和服务端私钥 放在同一个库里tmf.init(trustKeystore);// 上下文初始化,双向,两端证书的加载sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);} else {// 上下文初始化,单向sslContext.init(kmf.getKeyManagers(), null, null);}logger.info("上下文信息:{}", sslContext.getProtocol());logger.info("支持的协议:{}", JSONUtil.toJsonStr(sslContext.getSupportedSSLParameters().getProtocols()));return sslContext;} catch (KeyStoreException | KeyManagementException | NoSuchAlgorithmException | UnrecoverableKeyException |CertificateException | IOException e) {logger.info("Exception");e.printStackTrace();} finally {if (fileInputStream != null) {try {fileInputStream.close();} catch (IOException e) {e.printStackTrace();}}if (trustFileInputStream != null) {try {trustFileInputStream.close();} catch (IOException e) {e.printStackTrace();}}}return null;}}
客户端:
package com.xxx.yyy.common.socket.utils;import com.xxx.yyy.common.socket.config.SocketClientTLSConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;import javax.net.ssl.*;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.KeyStore;/*** @author H443745*/
public class SslSocketClientUtil {private static final Logger logger = LoggerFactory.getLogger(SslSocketClientUtil.class);public static final String PROTOCOL = "TLSv1.2";public static final String KEYSTORE_TYPE = "JKS";private static final String PROVIDER = "SunX509";private SslSocketClientUtil() {}public static SSLContext createSslContext(SocketClientTLSConfig tlsClientConfig) {//客户端证书库FileInputStream fileInputStream = null;KeyStore clientKeystore = null;//信任证书库FileInputStream trustFileInputStream = null;KeyStore trustKeystore = null;try {//信任证书库trustKeystore = KeyStore.getInstance(KEYSTORE_TYPE);trustFileInputStream = new FileInputStream(tlsClientConfig.getClientTrustKeystorePath());trustKeystore.load(trustFileInputStream, tlsClientConfig.getClientTrustKeystorePassword().toCharArray());//信任库TrustManagerFactory tmf = TrustManagerFactory.getInstance(PROVIDER);tmf.init(trustKeystore);//初始化SSL上下文SSLContext ctx = SSLContext.getInstance(PROTOCOL);logger.info("缺省安全套接字使用的协议:{} ", ctx.getProtocol());//是否双向验证boolean clientModeEnabled = tlsClientConfig.isClientModeEnabled();if(clientModeEnabled){//客户端证书库clientKeystore = KeyStore.getInstance(KEYSTORE_TYPE);fileInputStream = new FileInputStream(tlsClientConfig.getClientKeystorePath());clientKeystore.load(fileInputStream, tlsClientConfig.getClientKeystorePassword().toCharArray());// 密钥库/// KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());KeyManagerFactory kmf = KeyManagerFactory.getInstance(PROVIDER);kmf.init(clientKeystore, tlsClientConfig.getClientKeystorePassword().toCharArray());ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);} else{ctx.init(null, tmf.getTrustManagers(), null);}return ctx;} catch (Exception e) {e.printStackTrace();logger.error("failed to load KeyStore.", e);} finally {if (fileInputStream != null) {try {fileInputStream.close();} catch (IOException e) {e.printStackTrace();}}if (trustFileInputStream != null) {try {trustFileInputStream.close();} catch (IOException e) {e.printStackTrace();}}}return null;}@SuppressWarnings("unchecked")public static SSLSocketFactory createSocketFactory(SocketClientTLSConfig tlsClientConfig) {SSLContext sslContext = createSslContext(tlsClientConfig);if (sslContext == null) {logger.error("failed to create SSLSocketFactory.");return null;}logger.info("Protocol:{}", sslContext.getProtocol());return sslContext.getSocketFactory();}public static SSLSocket createSocket(SocketClientTLSConfig tlsClientConfig, String host, int port, HostnameVerifier hostnameVerifier) throws SSLException {SSLSocketFactory ssf = createSocketFactory(tlsClientConfig);if (ssf == null) {logger.error("SSLSocketFactory should not be null.");return null;}SSLSocket socket = null;try {socket = (SSLSocket) ssf.createSocket(host, port);// TODO-WANG later need TLSv1.3// socket.setEnabledProtocols(new String[]{"TLSv1.3"});socket.setSoTimeout(10000);} catch (IOException e) {logger.error("failed to createSocket, host={}, port={}", host, port, e);}if (socket == null) {logger.error("SSLSocketFactory not created.");return null;}if (hostnameVerifier != null && !hostnameVerifier.verify(socket.getInetAddress().getHostName(), socket.getSession())) {throw new SSLException("\"" + socket.getInetAddress().getHostName() + "\" identity was not confirmed");}return socket;}
}
OpenSSL 证书相关推荐
- python openssl 证书加解密过程感觉是这样
python openssl 证书加解密过程感觉是这样 第一步 生成2048 bit的PEM格式的RSA Key:Key.pem openssl genrsa -out Key.pem -f4 204 ...
- signature=1e627a907c86a2ecea855afa2fce9a87,熟练掌握 openssl 证书命令说明
熟练掌握 openssl 证书命令说明 发布时间:2020-05-10 09:03:43 来源:51CTO 阅读:257 作者:17gongdeng 熟练掌握 openssl 证书命令说明 2.在我电 ...
- OpenSSL证书认证过程
OpenSSL证书认证过程 游戏服务端这块,之前是很少用SSL的,毕竟游戏里的数据没有什么保密的必要,登录.充值也是传输签名,不涉及密码什么的.不过这几年,HTTPS普及得比较快,H5游戏发展迅速.H ...
- linux下 openssl证书签发
在linux已经集成了openssl组件,因此博主利用例子讲解如何在linux系统下签发证书,因为个人证书时不受谷歌浏览器认可的,所以自签发证书只能在火狐浏览器下测试使用! 1 openssl证书生成 ...
- openssl 证书生成手册
1.首先要生成服务器端的私钥(key文件): openssl genrsa -des3 -out server.key 1024 运行时会提示输入密码,此密码用于加密key文件(参数des3便是指加密 ...
- openssl证书及配置
我的环境是:Linux+Apache+MySQL+PHP 1.下载openssl 及相关依赖 #yum install -y openssl 2.进入目录 /etc/pki/tls/certs #cd ...
- linux openssl 证书,Linux上的openSSL证书验证
JKJS 得到了我自己的问题的答案: 1)通过以下命令创建根CA证书: openssl req -newkey rsa:1024 -sha1 -keyout rootkey.pem -out root ...
- openssl证书相关
openssl genrsa -out server.key 1024(不要求输入密码) openssl req -new -key server.key -out server.csr cat se ...
- C++使用OpenSSL证书API
本文主要介绍如果在C++中使用OpenSSL的证书相关API.(基于OpenSSL 1.0.2k版本,不同版本可能API会有一些差异,但大体应该类似) 使用下面方法前,需要全局调用一次(无需多次调用) ...
- openssl 证书验证
本节中我们快速浏览一下证书验证的主干代码.读者可以采用上节中生成的VC工程进行验证. 下面列出关键部分代码,为方便阅读,仅保留与证书验证强相关的代码,去掉了诸如变量定义.错误处理.资源释放等非主要代码 ...
最新文章
- JSPServlet学习手册
- python2版本和python3版本-python2和python3哪个版本新
- asm 32 /64
- X264编码流程详解(转)
- SpringBoot 整合 Redis 实现消息队列
- 一个简单例子:贫血模型or领域模型
- emoji表情mysql报错_让MySQL支持Emoji表情 mysql 5.6
- springboot获取客户端发来的数据
- ReactNative入门 —— 动画篇(下)
- 笔试题: 数据库 已看1 一些关键的sql语句练习 和选择题 有用 sql语句练习 挺好...
- pytorch中tensor转numpy
- python tuple用处_Python入门之最少必要知识
- 学生成绩排名 (用结构体数组按成绩排名)
- [编译原理]FIRST集合FOLLOW集的介绍和求解
- redis rua解决库存问题_Redis事务
- QQ浏览器性能提升之路-windows性能分析工具篇
- Swift实战-豆瓣电台(三)获取网络数据
- 订单系统设计 --- 订单中心存储方案
- ttl mysql_TTL 生存时间
- 多旅行商问题:鹈鹕优化算法(Pelican Optimization Algorithm,POA)求解多仓库多旅行商问题(提供Matlab代码)
热门文章
- Mycloud Home offline 排查
- FCC认证和FCC ID认证获证后标签该怎么打?
- 多功能数字钟c语言单片机PPT,基于51单片机多功能数字钟的设计
- 毕业设计 单片机超声波雷达系统 - 嵌入式
- 武汉新华电脑学校计算机协会,重庆新华电脑学校计算机管理协会更名庆典
- 大数据创新在广告营销中的应用(上)
- 计算机常用英语词汇及读音,表示显示的英文单词与标准读音
- MySQL查询时记录行号rownum MySQL查询显示行号MySQL查询显示行号MySQL流水号自MySQL自增行号
- java rails orm_rails知名应用和工具
- 从零教你写专利之开宗明义篇