OpenSSL(2)创建私有证书颁发机构
如果想要建立自己的CA, OpenSSL已经包含了所有你需要的东西。所有的操作都通过纯命令行执行,虽然不那么友好,整个过程也比较长,但是这可以让你去思考每个细节。
我建议自己创建一套私有的 CA主要是出于教学的目的,不过还有一些别的原因。OpenSSL的CA天然满足个人或者小团体的需求,例如在开发环境使用一套CA比到处使用自签名的证书好得多。同时还可以通过客户端证书来提供双向验证,这可以极大地提高敏感Web应用的安全性。
运行私有CA最大的挑战不是设置问题,而是如何保证基础结构的安全。例如根密钥必须离线保存,因为所有的安全都依赖它。另一方面, CRL和OCSP响应程序证书必须定期进行更新,而这会要求根密钥保持联机。
功能和限制
我们会创建一个与公共CA类似的私有CA架构。会先有一个根CA,然后创建其他的二级CA。接着我们会通过CRL和OCSP服务提供证书吊销信息。为了让根CA的私钥可以离线保存, OCSP响应程序需要使用它们自己的身份。这并非是最简单的CA,但是相对来说比较安全。另外二级CA会在技术上进行限制,只能给允许的主机名签发证书
完成设置之后,必须将根证书安全地分发给所有客户端。一旦根证书分发完毕,就可以开始签发客户端和服务器证书了。有一个限制是以这种方式设置的OCSP响应程序主要用来测试,因为只能承受比较小的负载。
创建根 CA
创建全新的CA有几个步骤:配置、创建目录结构和初始化密钥文件,最后生成根密钥和证书。本节描述了整个过程和常见的CA操作。
1)根CA配置
创建CA之前,我们需要先准备一个配置文件告诉OpenSSL我们希望的配置。一般情况下并不需要配置文件,但是根CA的创建操作复杂,使用配置文件可以简便很多。 OpenSSL的配置文件很强大,在开始之前我建议你熟悉一下这些配置的功能(命令行上使用man config命令)。
配置文件第一部分包括了CA的名称、基础URL和CA可分辨名称等基本信息。因为这些配置都很灵活,只需配置一次即可。
[default]
name = root-ca
domain_suffix = example.com
aia_url = http://$name.$domain_suffix/$name.crt
crl_url = http://$name.$domain_suffix/$name.crl
ocsp_url = http://ocsp.$name.$domain_suffix:9080
default_ca = ca_default
name_opt = utf8,esc_ctrl,multiline,lname,align
[ca_dn]
countryName = "GB"
organizationName = "Example"
commonName = "Root CA"
第二部分直接控制了CA的操作。有关每个设置的完整信息,可以通过ca命令来获取它的文档(命令行上输入man ca)。大部分命令从字面意思就可以很容易理解,我们需要告诉OpenSSL存放文件的路径。因为根CA只用作二级CA的签发,所以我把有效期设置为10年。另外默认情况下使用SHA256作为签名算法。
默认策略( policy_c_o_match)限制了这张CA签发的证书的国家名和组织名会与CA本身一样。对于公共CA来说很少会有这样的设置,但对于私有CA来说这种方式比较合适:
[ca_default]
home = .
database = $home/db/index
serial = $home/db/serial
crlnumber = $home/db/crlnumber
certificate = $home/$name.crt
private_key = $home/private/$name.key
RANDFILE = $home/private/random
new_certs_dir = $home/certs
unique_subject = no
copy_extensions = none
default_days = 3650
default_crl_days = 365
default_md = sha256
policy = policy_c_o_match
[policy_c_o_match]
countryName = match
stateOrProvinceName = optional
organizationName = match
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
第三部包含了req命令的配置, req命令只会在创建自签发根证书的时候用到一次。最重要的部分是扩展:基本限制( basicContraints)扩展表明这个证书是一张CA,密钥用法( keyUsage)扩展用来说明这个CA的用处:
[req]
default_bits = 4096
encrypt_key = yes
default_md = sha256
utf8 = yes
string_mask = utf8only
prompt = no
distinguished_name = ca_dn
req_extensions = ca_ext
[ca_ext]
basicConstraints = critical,CA:true
keyUsage = critical,keyCertSign,cRLSign
subjectKeyIdentifier = hash
配置的第四部分包括了根CA创建证书所需要的信息。因为基本限制( basicContraints)扩展的设置,所有的证书都将成为CA,但是我们需要把pathlen设置为0,表示这些CA无法再签发新的CA了。
所有二级CA都会受到限制,也就是说他们签发的证书只能对一些域名的子集有效,并且会被限制使用场景。第一,扩展密钥用法( extendedKeyUsage)扩展限制了只能进行客户端验证( clientAuth)和服务器验证( serverAuth),也就是TLS的客户端和服务器验证。第二,名称限制( nameContraints)扩展限制了允许签发的域名只有example.com和example.org。理论上这样的设置让你可以签发二级CA给第三方,同时可以通过限制他们无法签发任意域名的主机名来保证安全。排除这两个IP段的要求来自CAB论坛的Baseline Requirements,该规范从技术上定义了对二级CA的限制。
实际上,名称限制( nameContraints)并不完美,因为当前还有很多主流的平台无法识别名称限制扩展。如果你将这个扩展标记为关键扩展,就会导致很多平台拒绝识别你的证书。如果将其标记为关键扩展,那么很多平台就不会识别这个扩展,导致名称限制实际没有任何效果。
[sub_ca_ext]
authorityInfoAccess = @issuer_info
authorityKeyIdentifier = keyid:always
basicConstraints = critical,CA:true,pathlen:0
crlDistributionPoints = @crl_info
extendedKeyUsage = clientAuth,serverAuth
keyUsage = critical,keyCertSign,cRLSign
nameConstraints = @name_constraints
subjectKeyIdentifier = hash
[crl_info]
URI.0 = $crl_url
[issuer_info]
caIssuers;URI.0 = $aia_url
OCSP;URI.0 = $ocsp_url
[name_constraints]
permitted;DNS.0=example.com
permitted;DNS.1=example.org
excluded;IP.0=0.0.0.0/0.0.0.0
excluded;IP.1=0:0:0:0:0:0:0:0/0:0:0:0:0:0:0:0
最后两部分的配置表示有了这个扩展的证书可以对OCSP响应进行签名。为了能够运行OCSP响应程序,我们生成一个特别的证书,并且将OCSP的签名能力赋予这张证书。从扩展可以看出这张证书不是一个CA:
[ocsp_ext]
authorityKeyIdentifier = keyid:always
basicConstraints = critical,CA:false
extendedKeyUsage = OCSPSigning
keyUsage = critical,digitalSignature
subjectKeyIdentifier = hash
2)根CA的目录结构
下面我们会创建“根CA配置”中说到的目录结构,并且会初始化一些CA操作中会用到的文件。
$ mkdir root-ca
$ cd root-ca
$ mkdir certs db private
$ chmod 700 private
$ touch db/index
$ openssl rand -hex 16 > db/serial
$ echo 1001 > db/crlnumber
我们会用到以下这几个目录。
certs/
存放证书的地方;证书在签名之后会放置到这个目录下。
db/
这个目录用于证书数据库( index),一些包括下一张证书以及CRL数字的文件。 OpenSSL
会创建额外需要的一些文件。
private/
这个目录会存放私钥,一个给CA使用,一个给OCSP响应程序使用。务必确保其他用户
都不能访问这个目录(事实上,如果你真的很在意这个CA,那么这台存放根证书和密钥
的服务器的用户账户必须尽可能少)。
3)根CA生成
我们需要分两步来创建根CA。首先,我们生成密钥和CSR文件。当我们使用-config开关之后,所有需要的信息都会从配置文件中加载进来
$ openssl req -new \
-config root-ca.conf \
-out root-ca.csr \
-keyout private/root-ca.key
第二步我们会创建自签名证书。 -extension开关指向了配置文件的ca_ext部分,这样可以激活根CA所需的扩展。
$ openssl ca -selfsign \
-config root-ca.conf \
-in root-ca.csr \
-out root-ca.crt \
-extensions ca_ext
4)数据库文件结构
db/index中的数据库是一个包含证书信息的明文文件,每行一个证书。我们刚刚创建根CA,现在这个文件只有一行信息
V 240706115345Z 1001 unknown /C=GB/O=Example/CN=Root CA
每一行包括以下6个以制表符分隔的值。
(1) 状态标记[ V表示有效( valid), R表示已吊销( revoked), E表示已过期( expired)]
(2) 过期时间(以YYMMDDHHMMSSZ格式表示)
(3) 吊销日期,如果没有被吊销则为空
(4) 序列号(十六进制)
(5) 文件路径(如果不知道就显示unknown)
(6) 可分辨名称
5)根CA操作
使用ca命令的-gencrl开关给新CA生成CRL:
$ openssl ca -gencrl \
-config root-ca.conf \
-out root-ca.crl
使用ca的的命令来签发证书。需要注意的是-extensions开关需要指向配置文件里面正确的部分(例如,你肯定不希望再生成另一个根CA)。
$ openssl ca \
-config root-ca.conf \
-in sub-ca.csr \
-out sub-ca.crt \
-extensions sub_ca_ext
如果要吊销证书,可以使用ca命令的-revoke开关,不过需要有一份你想吊销的证书的副本。不过因为所有的证书都存在certs/目录下,所以只需要知道序列号即可。如果知道证书的可分辨名称,就可以在数据库里面查到它的序列号了。
为-crl_reason开关中的值选择一个正确的理由。该值可以是以下这些值之一: unspecified、keyCompromise 、 CACompromise 、 affiliationChanged 、 superseded 、 cessationOfOperation 、certificateHold和removeFromCRL。
$ openssl ca \
-config root-ca.conf \
-revoke certs/1002.pem \
-crl_reason keyCompromise
6)创建用于OCSP签名的证书
首先我们需要给OCSP响应程序创建一个私钥和CSR。这两个操作对所有的非CA证书都适用,所以不需要指定配置文件:
$ openssl req -new \
-newkey rsa:2048 \
-subj "/C=GB/O=Example/CN=OCSP Root Responder" \
-keyout private/root-ocsp.key \
-out root-ocsp.csr
第二步需要使用根CA签发一张证书。 -extensions开关的值选择ocsp_ext,以确保设置了OCSP签名所需要的扩展。我将这个证书的生命周期减少为365天(原来默认是3650天)。这些OCSP证书是没有吊销信息的,所以无法吊销它们。因此你会希望尽可能减少它们的生命周期。 30天是一个比较好的选择,当然前提是你已经准备好频繁地创建新的OCSP证书。
$ openssl ca \
-config root-ca.conf \
-in root-ocsp.csr \
-out root-ocsp.crt \
-extensions ocsp_ext \
-days 30
现在你已经有了OCSP响应程序所需要的一切东西,可以直接在根CA所在的服务器上进行测试。当然,如果在生产环境中使用,就必须将OCSP响应程序的密钥和证书放到别的地方
$ openssl ocsp \
-port 9080
-index db/index \
-rsigner root-ocsp.crt \
-rkey private/root-ocsp.key \
-CA root-ca.crt \
-text
可以使用下面的命令来测试OCSP响应程序:
$ openssl ocsp \
-issuer root-ca.crt \
-CAfile root-ca.crt \
-cert root-ocsp.crt \
-url http://127.0.0.1:9080
输出结果中的verify OK表示已经成功验证签名,而good表示这张证书还没有被吊销。
Response verify OK
root-ocsp.crt: good
This Update: Jul 9 18:45:34 2014 GMT
创建二级 CA
创建二级CA的过程和根CA几乎完全一样。
1)二级CA配置
我们可以在前面根CA配置文件的基础上,进行一些适当的修改生成二级CA的配置。我们会把名称改为sub-ca并且使用另一个可分辨名称。我们将二级CA的OCSP响应程序放在另外一个端口,主要是因为ocsp命令不识别虚拟主机。如果为OCSP响应程序使用了适合的Web服务器,就可以完全避免使用特别的端口。该证书默认的生命周期是365天,我们会每隔30天生成全新的CRL。
将copy_extensions更改为copy意味着在生成新证书的时候,如果我们的配置文件里面没有设置某些扩展,那么就会使用CSR文件里面的扩展字段。进行此更改之后,在准备CSR文件的时候就可以加入别的一些需要的字段,这些信息会在生成证书的时候加入到证书里面。这个特性有几分危险(因为允许其他人可以在一定程度上直接控制证书里面的内容),不过我认为在较小的环境中这么做是可以的。
[default]
name = sub-ca
ocsp_url = http://ocsp.$name.$domain_suffix:9081
[ca_dn]
countryName = "GB"
organizationName = "Example"
commonName = "Sub CA"
[ca_default]
default_days = 365
default_crl_days = 30
copy_extensions = copy
在配置文件的最后面,我们会增加两个新的配置,分别用于服务器和客户端证书的生成。唯一的区别就是keyUsage和extendedKeyUsage扩展。注意到我们把basicContraints扩展的值设置为false。之所以这么做,原因在于我们会复制CSR文件里面的扩展。如果在配置文件中没有显示设置这个扩展,那么就可能会用到CSR文件中的basicContraints了。
[server_ext]
authorityInfoAccess = @issuer_info
authorityKeyIdentifier = keyid:always
basicConstraints = critical,CA:false
crlDistributionPoints = @crl_info
extendedKeyUsage = clientAuth,serverAuth
keyUsage = critical,digitalSignature,keyEncipherment
subjectKeyIdentifier = hash
[client_ext]
authorityInfoAccess = @issuer_info
authorityKeyIdentifier = keyid:always
basicConstraints = critical,CA:false
crlDistributionPoints = @crl_info
extendedKeyUsage = clientAuth
keyUsage = critical,digitalSignature
subjectKeyIdentifier = hash
改好配置文件之后,按照根CA的过程创建一个同样的目录结构,不过可以使用另外一个名称,比如sub-ca。
2)二级CA生成
与前面一样,创建二级CA需要两步。第一步生成密钥和CSR。当我们使用-config开关的时候,所有需要的信息都会从配置文件中加载进来。
$ openssl req -new \
-config sub-ca.conf \
-out sub-ca.csr \
-keyout private/sub-ca.key
第二步我们使用根CA来签发证书。 -extensions开关指向配置文件中的sub_ca_ext,从而使用二级CA所需要的扩展。
$ openssl ca \
-config root-ca.conf \
-in sub-ca.csr \
-out sub-ca.crt \
-extensions sub_ca_ext
3)二级CA操作
要签发服务器证书,可以在处理CSR文件的时候,在-extensions开关中指定server_ext:
$ openssl ca \
-config sub-ca.conf \
-in server.csr \
-out server.crt \
-extensions server_ext
要签发客户端证书,可以在处理CSR文件的时候,在-extensions开关中指定client_ext:
$ openssl ca \
-config sub-ca.conf \
-in client.csr \
-out client.crt \
-extensions client_ext
注意
当收到新证书申请请求的时候,你需要在对所有信息进行验证之后才能进行操作。你
需要确保所有资料符合规定,特别是当你处理的CSR文件是别人生成的时。特别要注
意证书的可分辨名称以及basicContraints和subjectAlternativeName扩展。
二级CA的CRL生成和证书的吊销过程与根CA是一样的。唯一不同的是OCSP响应程序所使用的端口;二级CA使用的是9081端口。推荐OCSP响应程序使用独立的证书,这样可以避免将二级CA部署到公开的服务器上.
本文摘自《OpenSSL攻略》
详细操作扩展https://www.cnblogs.com/sparkdev/p/10369313.html
OpenSSL(2)创建私有证书颁发机构的更多相关文章
- ssl协议,openssl,创建私有CA
SSL是Security Socket Layer:安全的套接字层 他介于HTTP和TCP协议层之间 SSL是Netscape公司开发的,属于个人 TLS是标准委员会制定的 OpenSSL是SSL的开 ...
- WinInet:HTTPS 请求出现无效的证书颁发机构的处理
首先,微软提供的WinInet库封装了对网页访问的方法. 最近工作需要从https服务器获取数据,都知道https和http网页的访问方式不同,多了一道证书认证程序,这样就使得https在请求起来比h ...
- CA机构介绍(Certificate Authority 域名SSL证书颁发机构)
SSL证书机构即CA机构的全称为Certificate Authority证书认证中心,只有通过WebTrust国际安全审计认证,根证书才能预装到主流浏览器,成为全球可信的ssl证书颁发机构. HTT ...
- SSL/TLS协议详解(中)——证书颁发机构
本文转载自SSL/TLS协议详解(中)--证书颁发机构 导语 上一篇中,我们讨论了关于Diffie Hellman算法的SSL/TLS密钥交换.我们最终认为需要第三方来验证服务器的真实性,并提出了证书 ...
- 无效的 URI: 未能分析证书颁发机构/主机
出 现该错误的原因是URL中少了一个斜杠,正常的URL是“http:”后边有两个斜杠,而我在修改配置文件中的URL的IP地址部分时,不小心删掉了一个 斜杠,例如:http:/blog.csdn.net ...
- 安装VS2012 update3提示缺少Microsoft根证书颁发机构2010或2011的解决方法
警告提示如图: (copy的百度贴吧的童鞋的截图) 解决方法: 下载2010.10或2011.10的根证书即可 直通车:http://maxsky.ys168.com/ ——05.||浮云文件||—— ...
- 无效 URI: 故障分析证书颁发机构/主机
无效 URI: 分析证书颁发机构/主机 出现该错误的原因是URL中少了一个斜杠.正常的URL是"http:"后边有两个斜杠,而我在改动配置文件里的URL的IP地址部分时.不小心删掉 ...
- 你正在从一个声称代表如下的证书颁发机构安装证书 alipay truest network,希望能知道程序是怎么实现的或相关资料
你正在从一个声称代表如下的证书颁发机构安装证书 alipay truest network,希望能知道程序是怎么实现的或相关资料
- 全球可信并且唯一免费的HTTPS(SSL)证书颁发机构:StartSSL
全球可信并且唯一免费的HTTPS(SSL)证书颁发机构:StartSSL http://blog.s135.com/startssl/ 购买权威机构的证书一年大概得七八千元,其实这是不值得的,所以一直 ...
随机推荐
- Android热修复技术原理详解
阿里Dexposed -- native解决方案 原理: 直接在native层进行方法的结构体信息对换,从而实现完美的方法新旧替换,从而实现热修复功能 他的思想完全来源于Xposed框架,完美诠释 ...
- View的事件机制
为了更好的研究View的事件转发,我们自定以一个MyButton继承Button,然后把跟事件传播有关的方法进行复写,然后添加上日志. import android.content.Context; ...
- 阶段3 3.SpringMVC·_03.SpringMVC常用注解_7 ModelAttribute注解
这个注解可以作用在方法上,也可以作用在参数上 演示 user里面有三个属性, 表单只提交了两个属性.缺少了date属性 date没有获取到值因为也没提交这个值. 下面返回的user对象.上面就会拿到 ...
- Jmeter之Cookie和Session处理
Jmeter之Cookie和Session处理 1.Cookie 添加方式:线程组-配置元件-HTTP Cookie 管理器,如下图: 2.Session 添加方式:线程组-前置处理器 -HTTP U ...
- 机器学习:gensim之Word2Vec 详解
一 前言 Word2Vec是同上一篇提及的PageRank一样,都是Google的工程师和机器学习专家所提出的的:在学习这些算法.模型的时候,最好优先去看Google提出者的原汁Paper和Proje ...
- minio 集群启动方法
Sample: export MINIO_ACCESS_KEY=<TENANT1_ACCESS_KEY> export MINIO_SECRET_KEY=<TENANT1_SECRE ...
- 【VS开发】进程线程及堆栈关系的总结
进程线程及堆栈关系的总结 突然想到进程的栈和线程的栈,就顺便说一下,线程的栈被自动分配到进程的内存空间中 进程和线程都是由操作系统所体会的程序运行的基本单元,系统利用该基本单元实现系统对应用的并发性. ...
- 记录几个常用的Css样式效果
1.更改字体,图标大小小于12px无效的问题 若我们设置font-size:10px是不会有效果的,需要使用 transform: scale(0.68); 更改字体最小大小 2.设置div边框虚化, ...
- synchronized(三) 锁的膨胀过程(锁的升级过程)深入剖析
警告⚠️:本文耗时很长,先做好心理准备................哈哈哈 本篇我们讲通过大量实例代码及hotspot源码分析偏向锁(批量重偏向.批量撤销).轻量级锁.重量级锁及锁的膨胀过程(也就是 ...
- [转帖]yum命令的使用与createrepo自建仓库教程
yum命令的使用与createrepo自建仓库教程 http://www.linuxe.cn/post-300.html 跟上篇一样 可以学习一下. 发布:TangLu2018-11-23 16:48 ...