目录

证书标准

编码格式

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 证书相关推荐

  1. python openssl 证书加解密过程感觉是这样

    python openssl 证书加解密过程感觉是这样 第一步 生成2048 bit的PEM格式的RSA Key:Key.pem openssl genrsa -out Key.pem -f4 204 ...

  2. signature=1e627a907c86a2ecea855afa2fce9a87,熟练掌握 openssl 证书命令说明

    熟练掌握 openssl 证书命令说明 发布时间:2020-05-10 09:03:43 来源:51CTO 阅读:257 作者:17gongdeng 熟练掌握 openssl 证书命令说明 2.在我电 ...

  3. OpenSSL证书认证过程

    OpenSSL证书认证过程 游戏服务端这块,之前是很少用SSL的,毕竟游戏里的数据没有什么保密的必要,登录.充值也是传输签名,不涉及密码什么的.不过这几年,HTTPS普及得比较快,H5游戏发展迅速.H ...

  4. linux下 openssl证书签发

    在linux已经集成了openssl组件,因此博主利用例子讲解如何在linux系统下签发证书,因为个人证书时不受谷歌浏览器认可的,所以自签发证书只能在火狐浏览器下测试使用! 1 openssl证书生成 ...

  5. openssl 证书生成手册

    1.首先要生成服务器端的私钥(key文件): openssl genrsa -des3 -out server.key 1024 运行时会提示输入密码,此密码用于加密key文件(参数des3便是指加密 ...

  6. openssl证书及配置

    我的环境是:Linux+Apache+MySQL+PHP 1.下载openssl 及相关依赖 #yum install -y openssl 2.进入目录 /etc/pki/tls/certs #cd ...

  7. linux openssl 证书,Linux上的openSSL证书验证

    JKJS 得到了我自己的问题的答案: 1)通过以下命令创建根CA证书: openssl req -newkey rsa:1024 -sha1 -keyout rootkey.pem -out root ...

  8. openssl证书相关

    openssl genrsa -out server.key 1024(不要求输入密码) openssl req -new -key server.key -out server.csr cat se ...

  9. C++使用OpenSSL证书API

    本文主要介绍如果在C++中使用OpenSSL的证书相关API.(基于OpenSSL 1.0.2k版本,不同版本可能API会有一些差异,但大体应该类似) 使用下面方法前,需要全局调用一次(无需多次调用) ...

  10. openssl 证书验证

    本节中我们快速浏览一下证书验证的主干代码.读者可以采用上节中生成的VC工程进行验证. 下面列出关键部分代码,为方便阅读,仅保留与证书验证强相关的代码,去掉了诸如变量定义.错误处理.资源释放等非主要代码 ...

最新文章

  1. JSPServlet学习手册
  2. python2版本和python3版本-python2和python3哪个版本新
  3. asm 32 /64
  4. X264编码流程详解(转)
  5. SpringBoot 整合 Redis 实现消息队列
  6. 一个简单例子:贫血模型or领域模型
  7. emoji表情mysql报错_让MySQL支持Emoji表情 mysql 5.6
  8. springboot获取客户端发来的数据
  9. ReactNative入门 —— 动画篇(下)
  10. 笔试题: 数据库 已看1 一些关键的sql语句练习 和选择题 有用 sql语句练习 挺好...
  11. pytorch中tensor转numpy
  12. python tuple用处_Python入门之最少必要知识
  13. 学生成绩排名 (用结构体数组按成绩排名)
  14. [编译原理]FIRST集合FOLLOW集的介绍和求解
  15. redis rua解决库存问题_Redis事务
  16. QQ浏览器性能提升之路-windows性能分析工具篇
  17. Swift实战-豆瓣电台(三)获取网络数据
  18. 订单系统设计 --- 订单中心存储方案
  19. ttl mysql_TTL 生存时间
  20. 多旅行商问题:鹈鹕优化算法(Pelican Optimization Algorithm,POA)求解多仓库多旅行商问题(提供Matlab代码)

热门文章

  1. Mycloud Home offline 排查
  2. FCC认证和FCC ID认证获证后标签该怎么打?
  3. 多功能数字钟c语言单片机PPT,基于51单片机多功能数字钟的设计
  4. 毕业设计 单片机超声波雷达系统 - 嵌入式
  5. 武汉新华电脑学校计算机协会,重庆新华电脑学校计算机管理协会更名庆典
  6. 大数据创新在广告营销中的应用(上)
  7. 计算机常用英语词汇及读音,表示显示的英文单词与标准读音
  8. MySQL查询时记录行号rownum MySQL查询显示行号MySQL查询显示行号MySQL流水号自MySQL自增行号
  9. java rails orm_rails知名应用和工具
  10. 从零教你写专利之开宗明义篇