如何制作和使用自签名证书

在计算机加密和安全领域中,我们会时常遇到:自签名安全证书。

因为自签名证书签发相对于商业证书流程简单,费用低廉(除了电费几乎不花钱),更新容易。所以在开发领域、甚至一些小众场景下特别常见,比如 K8S / MySQL 集群中的 TLS 认证,一些大的集团、公司的内网服务、网站安全证书、企业路由器设备的管理后台、用于管理企业员工的“安全准入客户端”等不乏使用这个方案。

本篇文章就来聊聊如何快速生成证书,以及如何安装部署到不同的环境中。

写在前面

经常有人说,使用自签名证书不安全,会导致中间人攻击。这里需要为自签名证书“正名”,如果你制作生成的证书被妥善保管(即不泄漏并被二次利用),并将其加入你的有限的设备(自用、团队使用)的证书信任列表中,在明确你的设备访问地址(不涉及DNS攻击),你是不会遇到中间人攻击的。

比如当你遇到类似下面的场景,不一定会遇到不安全的事情,有可能只是管理员忘记换掉过期证书、或者你自己生成证书后,使用了一台没有信任证书的设备进行访问、也可能是管理员压根没有想在公网签发证书,想做一个私有的网站:

多数时候我们看到的不安全的证书是因为应用错误配置、有心人基于 DNS 地址攻击、证书过期造成、甚至是我们未曾正确配置证书信任白名单造成的。

一旦我们正确生成证书,在妥善保存证书后,进行了有限设备的白名单设置后,我们的证书和商业证书的使用是几乎没有差别的(除了无法使用 OCSP、EV 证书使用上存在一定额外工作外)。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-m800NGZS-1612587763873)(https://attachment.soulteary.com/2021/02/06/after-trust.png)]

那么来聊聊如何快速生成证书。

使用命令行脚本生成自签名证书

最常见和通用的做法便是安装配置一个带有 openssl 环境的系统,然后使用命令行执行类似下面这样的命令:

openssl req -x509 -newkey rsa:2048 -keyout ssl/${fileName}.key -out ssl/${fileName}.crt -days 3600 -nodes ...

这里如果你选择不使用配置文件的话,得参考openssl 文档,附带一堆参数,或需要交互式的输入一堆选项,并祈祷在中间每一步没有输入出错,例如下面这样:

enerating a RSA private key
....................................................................................................................................................................................................................................................................++++
.............................................................++++
writing new private key to 'example.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:CN
State or Province Name (full name) [Some-State]:XX
Locality Name (eg, city) []:XXXX
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Example, Inc
Organizational Unit Name (eg, section) []:IT
Common Name (e.g. server FQDN or YOUR name) []:example.com
Email Address []:example@soulteary.com

相比之下,使用类似下面的配置生成证书会稍微容易那么一些:

#!/bin/shOUTPUT_FILENAME="lab.com"printf "[req]
prompt                  = no
default_bits            = 4096
default_md              = sha256
encrypt_key             = no
string_mask             = utf8onlydistinguished_name      = cert_distinguished_name
req_extensions          = req_x509v3_extensions
x509_extensions         = req_x509v3_extensions[ cert_distinguished_name ]
C  = CN
ST = BJ
L  = BJ
O  = HomeLab
OU = HomeLab
CN = lab.com[req_x509v3_extensions]
basicConstraints        = critical,CA:true
subjectKeyIdentifier    = hash
keyUsage                = critical,digitalSignature,keyCertSign,cRLSign #,keyEncipherment
extendedKeyUsage        = critical,serverAuth #, clientAuth
subjectAltName          = @alt_names[alt_names]
DNS.1 = lab.com
DNS.2 = *.lab.com
DNS.3 = *.page.lab.com">ssl/${OUTPUT_FILENAME}.confopenssl req -x509 -newkey rsa:2048 -keyout ssl/$OUTPUT_FILENAME.key -out ssl/$OUTPUT_FILENAME.crt -days 3600 -nodes -config ssl/${OUTPUT_FILENAME}.conf

类似的脚本,我曾在 Traefik 示例脚本中提到过: https://github.com/soulteary/traefik-example/blob/main/scripts/generate-certs.sh 。

还有更简单的方案吗?尤其是在有不断修改 DNS、希望使用脚本自动化签订证书的场景下?

快速生成证书

为此我写了一个脚本,并使用容器进行封装,以达到可以使用极其简的命令行来生成证书的目的,并借助容器简化掉了本地需要安装 openssl 依赖的问题,“开箱即用”。相关代码我已经开源,项目地址:https://github.com/soulteary/certs-maker

比如你想生成一个稍微复杂一些的站点证书,只需要执行下面这行命令就足够了:

docker run --rm -it -e CERT_DNS="domain.com;*.domain.com;*.a.domain.com" -v `pwd`/certs:/ssl soulteary/certs-maker

执行完毕你将会看到类似下面的日志:

User Input: { CERT_DNS: 'domain.com;*.domain.com;*.a.domain.com' }
Generating a RSA private key
................................................................................................................................................+++++
.........................................................+++++
writing new private key to 'ssl/domain.com.key'
-----

以及能够在 ssl 目录中看到我们生成的证书文件。

至于其他的使用方式,比如生成包含多个域名的混合证书、生成单个证书,只需要调整 CERT_DNS 参数的值即可。如果想进一步定制前文提到的证书细节,比如证书签发国家、省份等信息,可以参考开源项目仓库的使用方式,添加其他的参数,这里就不过多赘述了。

使用 docker-compose 生成

如果你希望将命令保存下来,作为代码存储在仓库里,也可以考虑编写一个 compose 文件:

version: '2'services:certs-maker:image: soulteary/certs-makerenvironment:- CERT_DNS=a.com;b.com;c.com;*.d.com;volumes:- ./certs:/ssl

将上面的内容保存为 docker-compose.yml,然后执行 docker-compose up ,你会在 certs 目录看到生成的证书文件。

使用证书

生成证书之后,来聊聊如何使用证书。

在各种系统上导入证书

导入证书可以参考下面的文档,过程都很简单,引导证书,然后重启需要使用证书的应用即可。

  • Apple 文档:在 iOS 和 iPadOS 中信任手动安装的证书描述文件
  • VMware 文档:在 Windows 主机上导入内部根 CA 证书
  • SSL 文档: 生成证书签名请求(CSR)在macOS钥匙串访问中
  • 群晖文档:使用自我签署证书

在 Java 应用中信任自签名证书

如果你使用的是 Java 应用访问自签名的网站,应用访问过程会出现因为证书错误而拒绝连接的错误。

解决这个问题并不复杂,只需要额外做一点点工作,将证书添加到 keystore 中,重启 Java 应用即可:

sudo keytool -import -alias charles -file /Path-To-Certs/key.crt -keystore $JAVA_HOME/jre/lib/security/cacerts -storepass changeit

这个操作对于证书过期的情况,也同样有效,早先有一篇文章有描述:《使用 Docker 和 Traefik v2 搭建 Confluence 7.3 》。

在 Debian / Ubuntu / Alpine 系统中信任证书

对于 Debian / Ubuntu 系统,信任证书相当简单,只需要将证书拷贝到“待安装目录”,然后执行证书更新命令即可:

cp *.crt /usr/local/share/ca-certificates/
update-ca-certificates

Alpine 也是一样,考虑我们经常在容器场景中使用它,所以这里直接给出一个完整的Dockerfile 示例:

FROM alpineRUN apk update && apk add ca-certificates && rm -rf /var/cache/apk/*ADD ./ssl/*.crt /usr/local/share/ca-certificates/RUN update-ca-certificates --fresh

搭建配合安装证书使用的 Web 服务

上文中如果想在客户端(尤其是手机)上安装证书,一定会遇到跨系统传输文件的问题。为了方便分发和安装,这里可以使用 Nginx 启动一个用于分享证书安装的 Web 服务。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Uqx9MFJ7-1612587763874)(https://attachment.soulteary.com/2021/02/06/get-your-certs.png)]

搭建通用服务

我们可以使用 Nginx 的 ngx_http_sub_module 和 ** ngx_http_autoindex_module** 模块构建一个能够自动列举证书目录的服务:

server {listen 80;server_name localhost;location = /favicon.ico {empty_gif;}location / {root /public;autoindex on;sub_filter '<h1>Index of /</h1>'  '<h1>Get Certs</h1>';sub_filter_once on;}
}

将上面的内容保存为 default.conf 后,再创建一个名为 docker-compose.yml 的配置文件:

version: '2'services:nginx:image: nginx:1.19.6-alpineports:- 8080:80volumes: - ./default.conf:/etc/nginx/templates/default.conf.template:ro- ./public:/public:ro

然后使用 docker-compose up 启动服务后,使用手机访问页面,就能够看到类似下面的页面,然后使用手机访问证书文件进行安装和信任就可以啦。

更简单的配置方式

上面的模式我们将配置和服务编排文件分拆成了两个文件,考虑到这个 Nginx 配置十分简单,那么我们是否有办法将其简化呢?

答案是有的,通过对 command 命令进行调整,我们可以将 Nginx 配置的创建和服务启动同时写在 docker-compose.yml 编排文件中:

version: '2'services:nginx:image: nginx:1.19.6-alpineports:- 8080:80volumes: - ./public:/public:rocommand: >/bin/sh -c "echo \"daemon off;\" >> /etc/nginx/nginx.conf;echo \"server {listen 80;server_name localhost;location = /favicon.ico {empty_gif;}location / {root /public;autoindex on;sub_filter '<h1>Index of /</h1>'  '<h1>Get Certs</h1>';sub_filter_once on;}}\" > /etc/nginx/conf.d/default.conf; nginx;"

最后

最近入手了三根雷电数据线,快过年了,或许可以折腾一下雷电数据线组网开发。

–EOF


我现在有一个小小的折腾群,里面聚集了一些喜欢折腾的小伙伴。

在不发广告的情况下,我们在里面会一起聊聊软件、HomeLab、编程上的一些问题,也会在群里不定期的分享一些技术沙龙的资料。

喜欢折腾的小伙伴欢迎扫码添加好友。(请注明来源和目的、实名入群,否则不会通过审核)

关于折腾群入群的那些事


本文使用「署名 4.0 国际 (CC BY 4.0)」许可协议,欢迎转载、或重新修改使用,但需要注明来源。 署名 4.0 国际 (CC BY 4.0)

本文作者: 苏洋

创建时间: 2021年02月06日
统计字数: 6822字
阅读时间: 14分钟阅读
本文链接: https://soulteary.com/2021/02/06/how-to-make-and-use-a-self-signed-certificate.html

如何制作和使用自签名证书相关推荐

  1. Spring项目使用mkcert制作自签名证书

    mkcert制作自签名证书,适用于内网需要https安全连接的项目. 第一步:下载mkcert,完成后改名为mkcert,方便后续操作,在同目录下运行cmd. 下载地址:Release Cleaned ...

  2. linux技能包【7】:制作 https 自签名证书

    文章目录 一.架构图 二.制作步骤 2.1 CA 文件 2.2 server 文件 2.3 查看文件信息 一.架构图 二.制作步骤 2.1 CA 文件 step1:生成CA机构的私钥 openssl ...

  3. 苹果企业签名证书制作详解

    iOS企业签名证书怎么制作呢? 下面小编讲述详细制作教程 首先,我们来介绍下什么是企业签名吧 众所周知,苹果开发者账号分三种:个人开发者账号($99/年).公司开发者账号($99/年).企业级开发者账 ...

  4. Ubuntu18.04 使用 openssl制作自签名证书

    执行"openssl verison",判断系统是否已安装openssl,若没有安装,请使用apt安装openssl. 一.图解自签名过程 二.关于 CRT PEM KEY CST ...

  5. iOS使用自签名证书实现HTTPS请求

    原文链接:http://www.jianshu.com/p/e6a26ecd84aa 由于苹果规定2017年1月1日以后,所有APP都要使用HTTPS进行网络请求,否则无法上架,因此研究了一下在iOS ...

  6. iOS 用自签名证书实现 HTTPS 请求的原理实例讲解

    在16年的WWDC中,Apple已表示将从2017年1月1日起,所有新提交的App必须强制性应用HTTPS协议来进行网络请求.默认情况下非HTTPS的网络访问是禁止的并且不能再通过简单粗暴的向Info ...

  7. 自签名证书说明——自签名证书的Issuer和Subject是一样的。不安全的原因是:没有得到专业SSL证书颁发的机构的技术支持?比如使用不安全的1024位非对称密钥对,有效期设置很长等...

    一般的数字证书产品的主题通常含有如下字段: 公用名称 (Common Name) 简称:CN 字段,对于 SSL 证书,一般为网站域名:而对于代码签名证书则为申请单位名称:而对于客户端证书则为证书申请 ...

  8. C#制作、打包、签名、发布Activex全过程

    一.前言 最近有这样一个需求,需要在网页上面启动客户端的软件,软件之间的通信.调用,单单依靠HTML是无法实现了,因此必须借用Activex来实现.由于本人主要擅长C#,自然本文给出了用C#实现的范例 ...

  9. 签名证书无效”-在vCenter Server Appliance 6.5 / 6.7上使用Shell脚本重新生成和替换已过期的STS证书(76719)

    "签名证书无效"-在vCenter Server Appliance 6.5 / 6.7上使用Shell脚本重新生成和替换已过期的STS证书(76719) 上次更新时间:2020/ ...

  10. iOS 用自签名证书实现 HTTPS 请求的原理

    在16年的WWDC中,Apple已表示将从2017年1月1日起,所有新提交的App必须强制性应用HTTPS协议来进行网络请求.默认情况下非HTTPS的网络访问是禁止的并且不能再通过简单粗暴的向Info ...

最新文章

  1. 还搞不懂 Java NIO?快来读读这篇文章!
  2. C#中的继承与多态还有接口
  3. (转)Java中的守护线程
  4. 我们真正需要的目标(原名:制定目标你会吗?)
  5. 2017总结、2018展望
  6. linux mysql 磁盘_Linux运维知识之为Linux MySQL数据库设置磁盘限额
  7. 文件fluent_Win10 中解决FLUENT中UDF 的方法
  8. 聪明人自动焊锡机器人_自动焊锡机的基本焊锡原理
  9. python 路径拼接字符串_anaconda环境变量添加 python笔记
  10. 用递归方法求一个list的最大值
  11. 页面滚动可视区域的获取
  12. 基于SSM的旅游信息平台
  13. 利用Excel出库明细表批量生成送货单
  14. 南京大学计算机 国家重点实验室,南京大学
  15. 相机镜头等效焦距和实际焦距换算
  16. 数据分析实战(二):流浪地球8W多条评论分析
  17. sphinx安装及使用
  18. 搭建公众号微商城+小程序微商城 企业商城系统一条龙 拖拽可视化装修模板
  19. matlab bfs函数,Matlab脚本和函数
  20. 音视频学习-h264的NALU结构分析

热门文章

  1. 怎么使用水经注万能地图下载器制作百度行政区划个性化地图
  2. 如何学习SAP系统并从事相关职业
  3. Access入门之索引查询
  4. 2020年第十届C/C++ B组第二场蓝桥杯省赛真题
  5. python处理excel函数库_Python 操作 Excel 的函数库
  6. matlab查询函数用法,matlab函数用法总结
  7. 【Codecs系列】HEVC标准(三):大尺寸四叉树分割技术
  8. 计算机论文3000字文献,计算机学术论文3000字计算机学术毕业论文范文模板.pdf
  9. mac os adb下载
  10. 树莓派挂载8187L破解wifi