搭建私有CA并基于OpenSSL实现双向身份认证

时间:2022-09-25 22:37:25

0x00 前言

互联网上的Web应用由于用户数目广泛,都是采用单向身份认证的,只需要客户端验证服务端的身份。但如果是企业内部的应用对接,客户端数量有限,可能就会要求对客户端也做身份验证,这时就需要一个双向认证方案。本文通过搭建私有CA,利用OpenSSL工具,实现服务端与客户端的双向身份认证。安全协议采用HTTPS,这里用到的HTTPS除了能够进行身份认证以外,还能保证通信的保密性和完整性。

0x01 组建方案

组建方案如下图所示:

  • 整个方案包括一个私有CA、一个服务端、一个客户端,用于验证HTTPS双向身份认证的可行性。
  • 服务端的系统环境为CentOS7,Web服务器采用Tomcat7。客户端的系统环境为Windows,浏览器采用Firefox。
  • 由私有CA负责生成所有的私钥、证书等文件,并通过线下安全途径分发到服务端和客户端。
  • 其中,CA的私钥最为重要需加密后离线保管;服务端持有CA证书、服务器私钥、服务器证书3个文件;客户端持有CA证书、客户端私钥、客户端证书3个文件。
  • 客户端与服务端通过HTTPS安全协议进行双向身份认证、加密传输。另外,需要注意的是,HTTPS实现的是传输层的身份认证,不含应用层鉴权功能。

搭建私有CA并基于OpenSSL实现双向身份认证

0x02 私有CA的设置

安装与配置OpenSSL

安装OpenSSL

yum install openssl
yum install openssl-devel

OpenSSL默认安装完后,另外需要创建以下几个文件:

touch /etc/pki/CA/index.txt       #index文件用于记录已经签发的证书
touch /etc/pki/CA/serial
echo 00 > /etc/pki/CA/serial #serial文件用于存放证书的序列号,自动递增

完成该实验后index.txt中的信息为下面两条,即签发了两个证书分别是服务端证书和客户端证书

搭建私有CA并基于OpenSSL实现双向身份认证

因为,服务器证书请求文件的国家、省、市要和CA证书一致,这个在openssl.cnf默认配置中指定了。
可以通过修改/etc/pki/tls/openssl.cnf文件,调整为非强制一致。
将下面的几个match 修改为 optional

# For the CA policy
[ policy_match ]
countryName = match
stateOrProvinceName = match
organizationName = match

自签CA证书

生成根证书私钥 cakey.pem

openssl genrsa  -des3 -out cakey.pem  2048 这一步需要输入密码,密码用于加密私钥,使私钥非明文存于磁盘  

生成根证书签发申请文件 ca.csr

openssl req -new -key cakey.pem -out ca.csr -subj "/C=CN/O=CAorganization/CN=myCA"

自签发根证书 cacert.pem

openssl x509 -req -days 3650 -sha256 -extensions v3_ca -signkey cakey.pem -in ca.csr -out  cacert.pem  

服务端的私钥与证书

生成服务端私钥 serverkey.pem

openssl genrsa -out serverkey.pem 2048  

生成证书请求文件 server.csr

openssl req -new \
-sha256 \
-key serverkey.pem \
-subj "/C=CN/ST=myprovince/L=mycity/O=myorganization/OU=mygroup/CN=myserver.test.com" \
-reqexts SAN \
-config <(cat /etc/pki/tls/openssl.cnf \
<(printf "[SAN]\nsubjectAltName=DNS:myserver.test.com,DNS:myserver2.test.com")) \
-out server.csr

使用根证书签发服务端证书 servercert.pem

openssl ca -in server.csr \
-md sha256 \
-days 3650 \
-keyfile cakey.pem \
-cert cacert.pem \
-extensions SAN \
-config <(cat /etc/pki/tls/openssl.cnf \
<(printf "[SAN]\nsubjectAltName=DNS:myserver.test.com,DNS:myserver2.test.com")) \
-out servercert.pem

客户端的私钥与证书

生成客户端私钥 clientkey.pem

openssl genrsa -out  clientkey.pem 2048  

生成证书请求文件 client.csr

openssl req -new \
-sha256 \
-key clientkey.pem \
-subj "/C=CN/ST=myprovince/L=mycity/O=myorganization/OU=mygroup/CN=myclient.test.com" \
-reqexts SAN \
-config <(cat /etc/pki/tls/openssl.cnf \
<(printf "[SAN]\nsubjectAltName=DNS:myclient.test.com,DNS:myclient2.test.com")) \
-out client.csr

使用根证书签发客户端证书 clientcert.pem

openssl ca -in client.csr \
-md sha256 \
-days 3650 \
-keyfile cakey.pem \
-cert cacert.pem \
-extensions SAN \
-config <(cat /etc/pki/tls/openssl.cnf \
<(printf "[SAN]\nsubjectAltName=DNS:myclient.test.com,DNS:myclient2.test.com")) \
-out clientcert.pem

0x03 服务器端的设置

安装Java、Tomcat、创建JKS存放目录

Java、Tomcat安装完后 https://www.cnblogs.com/xdyixia/p/11653694.html

创建存放JKS文件的目录,服务端的Tomcat将用到的JKS格式的私钥和证书

mkdir -p  /data/live  #此目录之后用于存放JKS文件

把服务端私钥和证书制作成JKS文件

#得到 fullchain_and_key.p12
openssl pkcs12 -export -in servercert.pem -inkey serverkey.pem -out fullchain_and_key.p12 -name ssl

搭建私有CA并基于OpenSSL实现双向身份认证

这一步需要输入密码,假设此处输入密码为: mypassword

#得到ssl.jks
keytool -importkeystore -deststorepass myJKSpassasdf -destkeypass myJKSpassasdf -destkeystore ssl.jks -srckeystore fullchain_and_key.p12 -srcstoretype PKCS12 -srcstorepass mypassword -alias ssl

搭建私有CA并基于OpenSSL实现双向身份认证

#移位文件到/data/live
mv ssl.jks /data/live

搭建私有CA并基于OpenSSL实现双向身份认证

把信任根证书制作成JKS文件

#得到ssl2.jks
keytool -import -alias cacert -file cacert.pem -keystore ssl2.jks -deststorepass myJKSpassasdf2 -destkeypass myJKSpassasdf2

搭建私有CA并基于OpenSSL实现双向身份认证

#移位文件到/data/live
mv ssl2.jks /data/live

搭建私有CA并基于OpenSSL实现双向身份认证

配置Tomcat

修改Tomcat的server.xml,配置HTTPS功能

 <Connector port="443" protocol="org.apache.coyote.http11.Http11Protocol"
URIEncoding="UTF-8" maxThreads="500" SSLEnabled="true" scheme="https" secure="true" clientAuth="true" sslProtocol="TLS"
keystoreFile="/data/live/ssl.jks" keystorePass="myJKSpassasdf"
truststoreFile="/data/live/ssl2.jks" truststorePass="myJKSpassasdf2"
sslEnabledProtocols="TLSv1,TLSv1.1,TLSv1.2,SSLv2Hello"
ciphers="TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
TLS_ECDHE_RSA_WITH_RC4_128_SHA,
TLS_RSA_WITH_AES_128_CBC_SHA256,
TLS_RSA_WITH_AES_128_CBC_SHA,
TLS_RSA_WITH_AES_256_CBC_SHA256,
TLS_RSA_WITH_AES_256_CBC_SHA,
SSL_RSA_WITH_RC4_128_SHA" />

一些参数说明:

  • port该设置为HTTPS端口号。
  • 如果clientAuth该设置为“false”,则为单向SSL验证,不需要验证客户端证书。
  • 如果clientAuth设置为“true”,表示强制双向SSL验证。
  • 如果clientAuth设置为“want”,则表示可以验证客户端证书,但如果客户端没有有效证书,也不强制验证。
  • keystore就是用来存服务端自身的私钥和证书。
  • truststore就是用来存根证书文件的。

搭建私有CA并基于OpenSSL实现双向身份认证

搭建私有CA并基于OpenSSL实现双向身份认证

在服务端强制HTTP访问跳转为HTTPS

在server.xml文件,将redirectPort的8443端口,一律改为443(因为我们之前已经设置了443端口作为HTTPS端口)
在web.xml文件,插入这样一段:

<login-config>
<!-- Authorization setting for SSL -->
<auth-method>CLIENT-CERT</auth-method>
<realm-name>Client Cert Users-only Area</realm-name>
</login-config>
<security-constraint>
<!-- Authorization setting for SSL -->
<web-resource-collection >
<web-resource-name >SSL</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>

重启tomcat生效

#关闭
cd /usr/local/tomcat/tomcat8/bin
./shutdown.sh
#查看是否关闭
ps -ef|grep java

搭建私有CA并基于OpenSSL实现双向身份认证

此信息说明还没关

#如果关不了,使用kill命令,直接杀死Tomcat进程
kill -9 12265

搭建私有CA并基于OpenSSL实现双向身份认证

此信息说明关了

#启动Tomcat
./startup.sh

查看tomcat日志

搭建私有CA并基于OpenSSL实现双向身份认证

0x04 客户端的设置

修改客户端hosts文件

hosts中加入一行 192.168.91.166  myserver.test.com
其中,假设192.168.91.166 是服务端的IP,根据实际情况改写。
注意:这里hosts文件作用是代替DNS域名解析,仅为测试使用。

客户端浏览器导入CA根证书

Firefox浏览器导入cacert.pem文件 即CA根证书

搭建私有CA并基于OpenSSL实现双向身份认证

搭建私有CA并基于OpenSSL实现双向身份认证

客户端浏览器导入自己的私钥和证书

X509格式转化为pkcs12格式的文件

openssl pkcs12 -export -in  clientcert.pem -inkey clientkey.pem    -out  client.p12 -name client_ssl  

这一步需要输入密码,假设此处输入密码为: mypassword

将client.p12导入到浏览器

搭建私有CA并基于OpenSSL实现双向身份认证

0x05 双向身份验证与效果

浏览器打开URL: https://myserver.test.com
选择客户端证书

搭建私有CA并基于OpenSSL实现双向身份认证搭建私有CA并基于OpenSSL实现双向身份认证

成功打开网站

搭建私有CA并基于OpenSSL实现双向身份认证

该实验主要根据以下博客实现

https://gamedun.github.io/-----https://runner-china.github.io/blog/2018/07/10/ca

其他参考

https://blog.csdn.net/cuofucsdn/article/details/78851673

https://blog.csdn.net/Ningdaxing1994/article/details/78790493

https://www.cnblogs.com/Anker/p/6018032.html (该博文包含单向验证和双向验证)

搭建私有CA并基于OpenSSL实现双向身份认证的更多相关文章

  1. 搭建私有CA

    一.实验目的 搭建私有CA并使其可以实现公司内部的的签名服务. 二.实验环境: 系统架构:Centos7(服务器).Centos6(需要申请证书的服务器)需要的软件包:openssl.openssl- ...

  2. 搭建私有CA并实现证书颁发

    一.搭建私有CA服务器 1.安装包 # yum -y install openssl 2.生成密钥对儿 # cd /etc/pki/CA # (umask 077;openssl genrsa -ou ...

  3. linux下安装EJBCA 搭建私有CA服务器

    linux下安装EJBCA 搭建私有CA服务器 EJBCA是一个全功能的JAVA的CA系统软件,我们可以用此搭建私有CA服务器: 一:首先我的测试环境: 1.  linux mint18.3 62位: ...

  4. SharePoint 2013 配置基于表单的身份认证

    前 言 这里简单介绍一下为SharePoint 2013 配置基于表单的身份认证,简单的说,就是用Net提供的工具创建数据库,然后配置SharePoint 管理中心.STS服务.Web应用程序的三处w ...

  5. ASP&period;NET Web API 2系列&lpar;四&rpar;:基于JWT的token身份认证方案

    1.引言 通过前边的系列教程,我们可以掌握WebAPI的初步运用,但是此时的API接口任何人都可以访问,这显然不是我们想要的,这时就需要控制对它的访问,也就是WebAPI的权限验证.验证方式非常多,本 ...

  6. &period;NetCore WebApi——基于JWT的简单身份认证与授权(Swagger)

    上接:.NetCore WebApi——Swagger简单配置 任何项目都有权限这一关键部分.比如我们有许多接口.有的接口允许任何人访问,另有一些接口需要认证身份之后才可以访问:以保证重要数据不会泄露 ...

  7. springboot结合jwt实现基于restful接口的身份认证

    基于restful接口的身份认证,可以采用jwt的方式实现,想了解jwt,可以查询相关资料,这里不做介绍~ 下面直接看如何实现 1.首先添加jwt的jar包,pom.xml中添加依赖包: <de ...

  8. Linux系统搭建私有CA证书服务器

    一.CA简介 CA是什么?CA是Certificate Authority的简写,从字面意思翻译过来是凭证管理中心,认证授权.它有点类似我们生活中的身份证颁发机构,这里的CA就相当于生活中颁发身份证的 ...

  9. 基于JWT的token身份认证方案

    一.使用JSON Web Token的好处? 1.性能问题. JWT方式将用户状态分散到了客户端中,相比于session,可以明显减轻服务端的内存压力. Session方式存储用户id的最大弊病在于S ...

随机推荐

  1. vSphere Client无法连接到服务器 出现未知错误的解决方法

    VMware ESXi服务器虚拟机在正常使用过程中,有时候会突然出现远程连接不上的问题,那么这个时候使用vSphere Client连接会出现如下错误: 虽然连接不上,但是可以ping通,所以分析有可 ...

  2. 神奇的输入 while(cin&gt&semi;&gt&semi;&period;&period;&period;&period;)如何在遇见换行之后进入下一层循环读入

    cin>>m>>n; ;i<=m;i++) { ; char ch=' '; ) //在遇到换行之后进入下一层循环读入. { x++; cin>>c[x]; ...

  3. A&ast;算法为什么是最优的

    图搜索的A*算法有两种情况: hn是可采纳的,但是不是满足一致性 如果满足一致性,A*算法的实现要简单一些:即使不检查closed节点的状态重复,也能得到最优的结果 下面是证明最优性的一些关键点: 1 ...

  4. (转载)Convolutional Neural Networks卷积神经网络

    Convolutional Neural Networks卷积神经网络 Contents 一:前导 Back Propagation反向传播算法 网络结构 学习算法 二:Convolutional N ...

  5. 仿百度壁纸客户端(一)——主框架搭建&comma;自定义Tab&plus;ViewPager&plus;Fragment

    仿百度壁纸客户端(一)--主框架搭建,自定义Tab+ViewPager+Fragment 百度壁纸系列 仿百度壁纸客户端(一)--主框架搭建,自定义Tab + ViewPager + Fragment ...

  6. &lbrack;转&rsqb;Using Angular in Visual Studio Code

    本文转自:https://code.visualstudio.com/docs/nodejs/angular-tutorial Using Angular in Visual Studio Code ...

  7. 草珊瑚理解IFC&lpar;inline formatting context&rpar;

    1. 认识字体font-family 字体渲染的实际高度, 由字体本身的设置(升部ascender,降部descender,大写字母高度Capital Height,小写字母高度X-Height等等) ...

  8. k8s常用命令记录

    目录 kubectl常用命令 kubectl get pod -n dev 查看日志 查看pod详情 删除pod 删除job 进入pod里面 查看namespace 创建namespace 删除nam ...

  9. Scala2&period;10&period;4在CentOS7中的安装与配置

    随着基于内存的大数据计算框架——spark的火爆流行,用于编写spark内核的Scala语言也随之流行开来.由于其编写代码的简洁性,受到了越来越多程序员的喜爱.我今天给大家展示的时Scala2.10. ...

  10. Pandas v0&period;23&period;4手册汉化

    Pandas手册汉化 此页面概述了所有公共pandas对象,函数和方法.pandas.*命名空间中公开的所有类和函数都是公共的. 一些子包是公共的,其中包括pandas.errors, pandas. ...