TLS 证书及自签发

/ Developer / 没有评论 / 350浏览

什么是 TLS

简单来说就是一种利用密码学证书使数据能够在互联网内加密安全传输的一种协议. 目前常见的应用场景就是客户端和服务器之间数据交互的加密(这里的客户端和服务端是一个相对概念, 我们通常把发起请求的一方认为是客户端, 把处理请求的一方认为是服务端), 比如浏览器使用的 https 协议就是基于这类协议的一个衍生协议, 目的就是防止非法数据传输和抵御中间人嗅探和篡改, 保证数据安全性. 另外 TLS 准确来说它是 传输层安全性协议 的一类, 由 SSL2.x 升级 SSL3.x 后改名而来, 本文用 TLS 泛指高版本的 传输层安全性协议. 更多有关 TLS 的介绍请参见:

TLS 的常见应用类型

常见的应用类型可以分为 单向认证双向认证 两类; SSL单向认证和双向认证的区别主要可以归纳为以下几点:

  1. 单向认证只要求站点部署了ssl证书就行,任何用户都可以去访问(IP被限制除外等),只是服务端提供了身份认证。而双向认证则是需要是服务端需要客户端提供身份认证,只能是服务端允许的客户能去访问,安全性相对于要高一些
  2. 双向认证SSL 协议的具体通讯过程,这种情况要求服务器和客户端双方都有证书。
  3. 单向认证SSL 协议不需要客户端拥有CA证书,以及在协商对称密码方案,对称通话密钥时,服务器发送给客户端的是没有加过密的(这并不影响SSL过程的安全性)密码方案。
  4. 如果有第三方攻击,获得的只是加密的数据,第三方要获得有用的信息,就需要对加密的数据进行解密,这时候的安全就依赖于密码方案的安全。而幸运的是,目前所用的密码方案,只要通讯密钥长度足够的长,就足够的安全。这也是我们强调要求使用128位加密通讯的原因。
  5. 一般Web应用都是采用单向认证的,原因很简单,用户数目广泛,且无需做在通讯层做用户身份验证,一般都在应用逻辑层来保证用户的合法登入。但如果是企业应用对接,情况就不一样,可能会要求对客户端(相对而言)做身份验证。这时就需要做双向认证。

TLS 加密流程

没时间解释了, 请自行百度, 注意区分单项加密和双向加密即可

TLS 证书制作

相关概念

在网上找如何签发证书的文章, 基本都是作者整理好的一梭子 Shell, 直接拿来用就可以了 (哈哈, 我自己写文章的时候也会这么干), 但是, 由于证书的事关安全的重要性, 如果对相关概念不清楚, 容易产生"为什么要这么生成, 一句命令不是更好"这种思想就可能会导致证书在使用过程中出现各种问题, 管理混乱. 所以, 如果对这些东西不熟悉或者不理解, 咱们就先来一起捋一捋签发相关的概念和流程:

  1. 证书是一份包含公钥与其他辅助内容的一种文件
  2. 除了CA证书外, 证书都被上一层证书的公钥签名
  3. 既然证书内包含公钥, 那么对应的就会有相应的私钥
  4. 证书颁发一般经过3个过程: a. 拥有一个私钥 b. 用私钥创建一个颁发证书的请求 c. 上级 CA 接收请求之后核验身份, 通过之后将请求文件中的内容取出生成证书并用自己的 CA 证书及私钥对生成的证书文件签名, 并在该证书当中留下自己 CA 的相关信息, 形成整条信任链
  5. X.509 证书包含三个文件:keycsrcrt。 a. key 是服务器上的私钥文件,用于对发送给客户端数据的加密,以及对从客户端接收到数据的解密 b. csr 是证书签名请求文件,用于提交给证书颁发机构(CA)对证书签名 c. crt 是由证书颁发机构(CA)签名后的证书,或者是开发者自签名的证书,包含证书持有人的信息,持有人的公钥,以及签署者的签名等信息

备注:在密码学中,X.509是一个标准,规范了公开秘钥认证、证书吊销列表、授权凭证、凭证路径验证算法等。

综上所述, 基本就概括和解释了网上流传的 openssl 命令的作用和理由, 同时也就解释了像 12306 这样自签证书的网站为什么安装了他的CA证书之后浏览器就不会报警了. 再啰嗦两句, 一般创建 HTTP 相关的证书时不建议加密码, 否则在某些 HTTP 服务器启动时会要求输入密码.

实际操作

这里还是以 openssl 生成一对双向认证证书为例子(默认情况下,openssl 输出格式为 PKCS#1-PEM)

CA 颁发

首先, 我们先颁发自己的 CA证书, 所以第一步, 就得先来一个 CA 对应的私钥:

openssl genrsa -out ca.key 2048

然后, 由于是CA证书, 不需要经过谁审核, 所以这里没有创建请求文件的步骤, 就直接颁发 CA证书(其中 -subj 非必要):

简码全称示例含义
CCountry Name (2 letter code)CN国家代码
STState or Province Name (full name)SiChuan州或省份
LLocality Name (eg, city)ChengDu城市
OOrganization Name (eg, company)6xyun组织机构
OUOrganizational Unit Name (eg, section)Master机构部门
CNCommon Name (eg, fully qualified host name)6xyun CA域名或证书使用者
emailAddressEmail Addressusername@domain邮箱地址
# 如果在 Windows 使用 Git Bash 出现错误
# name is expected to be in the format /type0=value0/type1=value1/type2=... where characters may be escaped by \. This name is not in that format: ...
# 则需要在命令前加上
# MSYS_NO_PATHCONV=1
# 例如 MSYS_NO_PATHCONV=1 openssl ...
openssl req -new -x509 -days 365 -key ca.key -out ca.crt -subj "/C=CN/ST=SiChuan/L=ChengDu/O=6xyun/OU=Master/CN=6xyun CA/emailAddress=username@domain"

当然, 上面只是为了表现正确的步骤, 如果你实在不耐烦, openssl 也支持两步合成一步, -newkey 可以让 openssl 先生成一个私钥再用这个私钥自动完成 CA 颁发:

openssl req -newkey rsa:2048 -nodes -keyout ca.key -x509 -days 3650 -out ca.crt

以上就完成了 CA 私钥生成以及证书颁发;

服务端颁发

接下来服务端证书, 同样也是先生成私钥:

openssl genrsa -out server.key 2048

由于服务端经常需要使用 DNS别名, 所以必须生成一个配置文件生成V3版证书:

cat << EOF > server.cnf
[ req ]
distinguished_name = req_distinguished_name
req_extensions = v3_req

[ req_distinguished_name ]

[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName = @alt_names

[ alt_names ]
DNS.1 = *.domain.com
DNS.2 = *.domain.cn
IP.1 = 10.0.0.1
IP.2 = 192.168.0.1
EOF

然后是创建请求文件(同样 -subj 非必要):

openssl req -new -key server.key -out server.csr -subj "/C=CN/ST=SiChuan/L=ChengDu/O=6xyun/OU=Master/CN=Server/emailAddress=username@domain" -config server.cnf

最后就是作为 CA 管理员签发这个服务端证书:

openssl x509 -req -days 3650 -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt   -extensions v3_req -config openssl.cnf

经过上面的操作, 就得到了 server.crt 这个证书文件, 注意不要和请求文件 server.csr 混淆了.

客户端颁发

过程和服务器类似, 如果没有特殊需要颁发 V1版本即可:

# 生成私钥
openssl genrsa -out client.key 2048
# 生成请求文件
openssl req -new -key client.key -out client.csr -subj "/C=CN/ST=SiChuan/L=ChengDu/O=6xyun/OU=Master/CN=Client/emailAddress=username@domain"
# 生成证书
openssl x509 -req -days 3650 -in client.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out client.crt

GUI 工具

如果你觉得上面的操作麻烦, 推荐一个极好的全平台支持的生成/管理证书的工具: X Certificate and Key management

引用