首页
技术小册
AIGC
面试刷题
技术文章
MAGENTO
云计算
视频课程
源码下载
PDF书籍
「涨薪秘籍」
登录
注册
当SWOOLE遇上PHP
当SWOOLE遇上SERVER
当SWOOLE遇上TCP
当SWOOLE遇上PROTOCOL
Swoole的进程模型
Swoole的进程与热重载
守护进程二三事与Supervisor
番外:数字签名与数字证书
番外:OpenSSL与数字证书
当前位置:
首页>>
技术小册>>
Swoole入门教程
小册名称:Swoole入门教程
## OpenSSL 首先需要简要介绍的就是名为`openssl`的工具,简单说,它是`SSL/TLS`的开源实现,实现了相关的加密解密算法、具备数字证书管理等功能的一个程序。 > 至于安装方式嘛,相信难不倒各位童鞋的,键者秉持偷懒的心略过…… 我们先来简单回顾下自建CA需要处理些什么问题? * 我们需要能生成`不对称密钥`。 * 我们需要能基于`公钥`及一些`基础信息`生成`证书签名请求` * 我们需要能用`私钥`为`证书签名请求`签名,从而生成`数字证书` > 为了方便,以下可能会使用`CSR`描述`证书签名请求`;`CRT`表示`数字证书` ### 生成`RSA`密钥 那么,我们首先认识一下生成`RSA`密钥的命令吧: ```shell openssl genrsa -out -des3 rsa.key 4096 + `genrsa` 用于生成 RSA 密钥对的 OpenSSL 命令。 + `-out` 令生成的密钥对保存到文件 + `4096` RSA 模数位数 + `-des3` 使用 3-DES 对称加密算法加密密钥对,该参数需要用户在密钥生成过程中输入一个口令用于加密。今后使用该密钥对时,需要输入相应的口令。如果不加该选项,则不对密钥进行加密。 ``` 此时,会生成`rsa.key`文件,但注意,这个可不只是`私钥`哦,里边还有包括`p`、`q`在内的其他参数,所以通过`ca.key`直接推导出`公钥`。 > 虽然理论上,`RSA`算法中的`公钥`和`私钥`是没有本质区别的,仅知道任何一个都无法推导另一个出来,但如果有了`p`、`q`等参数就不一样了。 > 所以请妥善保管`ca.key`,这个文件其实等价于同时包含了`公钥`和`私钥`! 如果使用了`-des3`命令,则生成时会要求用户输入一个密码,并用该密码对生成的文件内容再做一次加密;除了`-des3`以外,还可以选择`-aes128`、`-aes256`等加密算法,相当于为生成的`rsa.key`再加了一层保险。 > 不过用的时候也要相应地使用密码解密就是了。 在整个数字证书体系中,可以认为,每一个实体都会唯一持有一对`不对称密钥`,这对密钥也是后续所有数字证书相关功能的身份验证基础。 > 这个实体可能是`CA`,也可能是`Server`或者`Client`。 > 目前工程上常用是`RSA`算法,但并不是只有`RSA`哦,有兴趣的童鞋可以自己去搜搜看~ ### 生成`CSR` 如果说`密钥`实现了身份的鉴别基础,那么`CSR`其实本质上就是更具体的身份信息,就像`基因`可能唯一标识了一个人,但这个人的社会属性如`姓名`、`经历` 等信息也是构成这个人不可或缺的部分。 > 所以生成`CSR`的时候,需要同时打包`公钥`和`基本信息`。 ```shell openssl req -new -days 365 -key rsa.key -out someone.csr + `req` 用于生成证书请求的 OpenSSL 命令。 + `-new` 生成一个新的证书请求。该参数将令 OpenSSL 在证书请求生成过程中要求用户填写一些相应的字段。 + `-days 365` 证书有效时间。 + `-key` 用于签名的CA私钥。 + `-out` 将生成的请求保存到文件。 ``` 执行这个命令的时候,会提示要求输入国家代码(Country Name)等信息,这是数字证书标准中要求`CSR`附带的基本信息,所以根据自己的情况填写即可,完成后即可得到`someone.csr`。 > 其中填写`Common Name`时注意,这里请填写的运行服务的主机可以正确解析的域名,本地调试的话可以使用`localhost`,否则可能会导致基于这个`数字证书`的网络服务(如,`https`)无法工作。 注意,这里虽然传入了`rsa.key`,但其实本质上是为了将`rsa.pub`写入`someone.csr`中,以便后续生成证书,并不是把`私钥`写入了`someone.csr`中哦。 ### 签名并生成`CRT` 生成证书其实就是用`私钥`对`证书请求`进行签名。 使用的`私钥`可以是自己的,也可以是别人的。如果是自己的,则表示自签名,就像我为自己带盐一样。如果是别人的,则表示别人为这个`证书请求`作担保。 > 一般这里的别人都承担着CA的职能。 ```shell openssl x509 -req -in someone.csr -signkey rsa.key -out rsa.crt - `x509` 操作符合x509标准的数字证书 - `-req` 传入一个`证书请求`,对其签名并输出`证书` - `-int` 待签名的`证书请求`文件。 - `-signkey` 用于签名的私钥。 - `-out` 将生成的证书保存到文件 ``` > x509其实是数字证书的文件格式标准,一般我们用的数字证书都是符合x509标准的。 ### 小结 应用的关键在于: * 要信任谁,则表现为信任其证书,本质是信任证书的签发机构。 * 要为谁做担保,则使用私钥为其请求签名,请求应包含被担保人的公钥。 ## 实战:我们来实现一组双向认证的数字证书体系吧 前文三个命令已经涵盖了`数字证书`管理体系中最核心的三个步骤,后续更复杂的参数其实也只是数字证书特性的灵活应用,所以现在我们来试着设计一个稍微复杂点的结构。 > 其实这才是键者之前在折腾的东西…… 假设我们现在有一个`Server`和一个`Client`,每当`Client`连接`Server`的时候,`Server`需要确认`Client`有自己信任的`CA`签发的`CRT`,而`Client`也需要确认`Server`有自己信任的`CA`签发的`CRT`。 > 理论上这两个`CA`可以是同一个,也可以是不同的两个,为了复杂起见Orz,吖不,为了强调两者并没有关联性,我们来设计一个不同的场景,以下会称作`SRV.CA`、`CLI.CA`,分别表示`SRV`信任的`CA`、`CLI`信任的`CA`。 那么我们可以简单梳理出,这个体系中有四个实体,分别是`SRV.CA`、`CLI.CA`、`SRV`、`CLI`。 ### 生成`CA` 那么我们先来看一下,怎么生成一个自签名的`CA`,因为生成过程其实是一样的,只是用途不同。 ```shell # 生成CA的`密钥对` openssl genrsa -out ca.key 4096 # 生成CA的`证书请求` openssl req -new -key ca.key -out ca.csr # 用CA的私钥为自己的`证书请求`签名,生成`数字证书` openssl x509 -req -in ca.csr -signkey ca.key -out ca.crt ``` > 其实`*.crt`包含的核心内容就是`基础信息`和`公钥`。 根据上述代码,我们可以轻松获得两个`CA`,以及它们的`密钥`和`数字证书`,我们现在已有的文件如下: ``` |- client.ca.key |- client.ca.crt |- server.ca.key \- server.ca.crt ``` > `CSR`其实只是中间文件,可以保留,也可以删除,这里先省略了。 ### 为`Server`和`Client`签发证书 先梳理一下思路,因为`SRV.CA`是`SRV`信任的证书签发机构,所以,要用`SRV.CA`给`Client`签发`数字证书`;同理,`Client.CA`其实是给`Server`签发证书的机构。 那么我们先来看看`Server`侧的生成代码: ```shell # 生成Server的`密钥对` openssl genrsa -out server.key 4096 # 生成Server的`证书请求` openssl req -new -key server.key -out server.csr # 用Client.CA的私钥为Server的`证书请求`签名,生成`数字证书` openssl x509 -req -in server.csr -signkey client.ca.key -out server.crt ``` > 这里与前边的自签名证书就不同了,用于签名的私钥变成了`client.ca.key`。 同理,我们可以推导出`Client`侧的签发代码: ```shell # 生成Client的`密钥对` openssl genrsa -out client.key 4096 # 生成Client的`证书请求` openssl req -new -key client.key -out client.csr # 用Server.CA的私钥为Client的`证书请求`签名,生成`数字证书` openssl x509 -req -in client.csr -signkey server.ca.key -out client.crt ``` 这样,我们就可以得到以下的文件集合: ```shell |- client.ca.key |- client.ca.crt |- server.ca.key |- server.ca.crt |- client.key |- client.crt |- server.key \- server.crt ``` 木有错,这些就是我们完成整套工作时需要的文件,作为管理者,我们再看看分发后的场景: ```shell \- ServerDirectory |- server.ca.crt |- server.key \- server.crt \- ClientDirectory |- client.ca.crt |- client.key \- client.crt ``` 实际工程中,我们应该仅分发足够应用的证书文件,特别是保护好私钥,私钥一旦泄漏,整个信任体系就会面临崩溃,特别是`CA`的私钥。 ## 小结 在去年的故事里,键者唠唠叨叨流水账了一波`数字证书`的工作机制,那么今年的第一篇文章,就来具体讲讲怎么样通过`OpenSSL`生成具备生产价值的数字证书…… > 其实键者一开始想写的只是怎么用`golang`实现`gRPC`的基于`TLS`的双向认证,没想到,故事越写越长,估计这个故事又要等下一期了…… 相信有悟性高的童鞋已经发现了,其实`CA`、`Client`、`Server`的身份都只是相对的,`Server`的私钥同样可以签发新的证书,真正起作用的是其工作时承担的角色而已。`CA`还可以继续签发`CA`,从而形成一条证书链,证书链可以实现分层的授权管理。 > 当然,OpenSSL其实有更详细的参数,可以约束一个签发的证书仅可用于充当`CA`、`Server`或者`Client`等等,但只要理解其核心原理,万变不离其宗,相信已经不需要键者啰嗦咯~ 最后的最后,其实管理各种证书是个很麻烦的事情,既牵涉到业务逻辑,又涉及各种密码的存管。别的不说光起名字就是个麻烦事,而且随着服务端、客户端的扩容,需要管理的证书只会多不会少,这块东西其实也是个问题。 > 键者目前是使用了一个叫`xca`的软件来管理证书,如果有童鞋有更好的推荐欢迎在评论中告诉键者~ ## 本篇关键词 TLS:Transport Layer Security,传输层安全协议 SSL:Secure Sockets Layer,可以认为是TLS的前身。
上一篇:
番外:数字签名与数字证书
该分类下的相关小册推荐:
Laravel(10.x)从入门到精通(八)
Magento零基础到架构师(安装篇)
Laravel(10.x)从入门到精通(十二)
Laravel(10.x)从入门到精通(十一)
Yii2框架从入门到精通(上)
PHP底层原理及源码分析
Magento中文全栈二次开发
Workerman高性能框架-GatewayWorker
Laravel(10.x)从入门到精通(十)
PHP面试指南
PHP程序员面试笔试真题与解析
HTTP权威指南