生成本地测试用https证书,支持通配符和多域名,初学OpenSSL

本文介绍了一种使用OpenSSL在本地环境中生成支持通配符和多域名的SSL证书的方法,包括生成根证书、域名证书及签名过程,适用于Windows系统的HTTPS全站化测试环境搭建。

18-01-26在v2ex上看到一妹纸发的《身为一个 21 岁的年轻程序员,我已经腰突了(躺》,哈哈,感同身受,想到这几天我左腿麻木持续了好几天,前几天屁股疼的只要坐下就站不起来,不过站着却一点事没有,然后坚持站了好几天,目前屁股不疼,腿麻的毛病还没有恢复。。。[后续]

封面图怎么发?

接触到的https

https站点生产环境和本地测试环境搭建以前也有点接触(Windows Server2008 2012、Win7+IIS、还没有接触过其他系统Mac OS算半个),比如生产环境的:从免费的AlphaSSL通配符证书申请(好像已经关掉了),到坐等2月27号Let’s Encrypt正式开通通配符证书接口。

为什么执意要通配符证书,其实不用也可以,不过要看服务器脸色,Windows Server2008不支持SNI哦,如果是腾讯云或者别的地方免费申请的单域名证书就有点惨了,目前了解到的针对这种单域名的只有加上端口才能多个域名同时使用。免费的Let’s Encrypt签的多域名证书3月要维护一次,感觉好累啊~

本地测试环境相对就简单多了,自己想怎么搞就怎么搞,证书想怎么签就就怎么签,谁要测试就在电脑上把根证书一装,妥妥的。

以前生成证书比较简单,直接用Windows Server系统自带功能证书颁发机构就可以完成证书的签发,也一直是这么干的,给我台式电脑ip签了一个证书,需要的功能开发基本上都满足了,要求其实并没有那么高@.@
网络上的一幅图

好了,为什么又扯出OpenSSL了呢,如果没有Windows Server,Win7是没有证书颁发机构这个玩意的,额外再装一个虚拟机吗?不方便,并且对证书颁发机构不够熟,高级点的证书还要好好研究。需要寻找别的方法了,首选就是OpenSSL了。

准备工作

因为用的是Win7系统,下载了Win32OpenSSL。以前没有怎么用过OpenSSL,用的最多也就是生成个把子RSA秘钥,对于签名和证书是从来没有接触过的,而外花了半天时间搜索学习生成ssl通配符和多域名证书的方法。

IIS全站https计划

准备这样对二级域名进行细分,举个栗子aa.com

  1. www .aa .com、aa .com:网页和接口
  2. static .aa .com:静态资源,图片、js等
  3. *.aa .com:其他功能站点子域名,广告、单独功能站点
  4. bb .com、cc .com:其他域名,备用

1、3、4是全部要上https的,2这个分http和https,js必须要https,图片之类的没有强制要求,默认全部是https的,让浏览器有把小绿锁。

根据这些域名,本地测试生成证书就有方向了,最好是一个证书解决,不然IIS配置麻烦的要死。用通配符和多域名解决。

生成本地测试证书

根据网上找到的资料,正常生成了证书。先生成根证书,然后生成域名证书,最后用根证书对域名证书签名。把根证书导入目标电脑上就能正常访问所有对应的域名了。

1. 创建根证书

@echo off
set OPENSSL_CONF=openssl.ini

echo 创建秘钥
pause
openssl genrsa -out LocalRootCA.key 2048

echo 生成证书并自签名
pause
openssl req -sha256 -new -x509 -days 3650 -key LocalRootCA.key -out LocalRootCA.crt -subj "/CN=LocalRootCA"

echo 完成
pause

2. 创建域名证书

@echo off
set OPENSSL_CONF=openssl.ini

echo 创建秘钥
pause
openssl genrsa -out aa.com.key 2048

echo 创建请求文件
pause
openssl req -new -sha256 -key aa.com.key -out aa.com.csr -subj "/CN=*.aa.com"

echo 生成证书并用根证书签名
pause
openssl x509 -req -in aa.com.csr -CA LocalRootCA.crt -CAkey LocalRootCA.key -CAcreateserial -days 3560 -out aa.com.crt -extfile aa.com.ini -extensions ext

echo 导出pfx,请输入密码
pause
openssl pkcs12 -export -out aa.com.pfx -inkey aa.com.key -in aa.com.crt

echo 完成
pause

3. 以上代码涉及到两个配置文件:

(1) openssl.ini就是OpenSSL安装目录中的配置文件,原封不动的(除了文件名)
(2) aa.com.ini是多域名配置列表,文件内容:

[ ext ]
subjectAltName = @dns

[ dns ]
DNS.1 = aa.com
DNS.2 = *.aa.com
DNS.3 = bb.com
DNS.4 = cc.com
DNS.5 = localhost
DNS.6 = 127.0.0.1

4. 测试

将根证书导入到系统受信任的根证书颁发机构里面,将生成的pfx文件导入到iis里面,站点绑定https,这时我电脑上弹出丢失证书链的提示,不过好像并没有什么影响。浏览器访问正常的很:
域名访问测试

生成的证书文件

#收尾
可以看到,通过OpenSSL本地已生成了支持通配符和多域名的证书,本地https全站化测试环境搭建的证书资源算是妥了,想要什么样的就立马生成什么样的,可以看到除了域名,IP也是可以支持进去的。

如果要切换到线上,要简单省钱,等到2月Let’s Encrypt就能提供完美的解决方案了,说到底还是买不起证书,我用免费的。

预告:证书搞完后,下一件已完成的事是把统计局的2017年5月发布的新的行政区划数据重新采集了一遍(省市区镇数据),含数据格式化和拼音标注,整个过程用纯js处理的,这个方法比较拿手,过段时间针对这个功能会单独发一篇文章。

[接续] 可能是躺久了或者是持续坐久了的的原因吧,来三亚将近20天一直猫在一间5平米不到的小屋里面,行李箱当桌子、床当凳子,矮了点。不过后面几天站着还好,至少没有屁股和腰疼的毛病,前段时间上班经历了第一次腰疼,疼了半个月,不过自己恢复了。少坐多站,坐也要坐好,躺也要躺好。

<think>我们可以在生成证书请求(CSR)时,通过OpenSSL命令行直接添加多个域名(SAN)。这需要创建一个配置文件,并在命令行中指定该配置文件。但是,用户要求直接在命令行中完成,而不想单独创建配置文件。然而,OpenSSL在命令行中直接指定多个SAN是有限制的,通常需要借助配置文件。不过,我们可以通过一个命令完成,将配置信息内联在命令中。 但是,OpenSSL 1.1.1及以上版本支持在命令行中直接指定SAN扩展。我们可以使用`-addext`参数来添加SAN条目。 以下是一个示例命令,用于生成一个包含多个域名的证书请求(CSR)私钥,同时通过命令行直接添加多个SAN: 步骤: 1. 生成私钥 2. 生成证书签名请求(CSR),并在命令行中指定主题信息以及多个SAN 示例命令: ```bash openssl req -new -nodes \ -newkey rsa:2048 \ -keyout server.key \ -out server.csr \ -subj "/C=CN/ST=Beijing/L=Beijing/O=Example Inc./OU=IT Department/CN=example.com" \ -addext "subjectAltName = DNS:example.com, DNS:www.example.com, DNS:test.example.com, IP:127.0.0.1" ``` 注意: - `-addext` 参数用于添加扩展项,这里我们添加了`subjectAltName`(主题备用名称),其中包含了多个DNS记录一个IP地址。 - 该命令需要OpenSSL 1.1.1及以上版本。 如果你需要生成自签名证书,可以使用以下命令(同样在一条命令中完成): ```bash openssl req -x509 -nodes \ -newkey rsa:2048 \ -keyout server.key \ -out server.crt \ -days 365 \ -subj "/C=CN/ST=Beijing/L=Beijing/O=Example Inc./OU=IT Department/CN=example.com" \ -addext "subjectAltName = DNS:example.com, DNS:www.example.com, DNS:test.example.com, IP:127.0.0.1" ``` 这样,生成证书就包含了多个SAN条目。 但是,如果你的OpenSSL版本低于1.1.1(例如1.0.2),则无法使用`-addext`参数。在这种情况下,你必须使用配置文件。不过,我们可以通过一个临时生成的配置文件来在一条命令中完成,避免手动创建文件。 对于低版本OpenSSL,可以使用以下方法(以bash为例): ```bash openssl req -new -nodes \ -newkey rsa:2048 \ -keyout server.key \ -out server.csr \ -subj "/C=CN/ST=Beijing/L=Beijing/O=Example Inc./OU=IT Department/CN=example.com" \ -config <(cat <<-EOF [req] distinguished_name = req_distinguished_name req_extensions = v3_req prompt = no [req_distinguished_name] C = CN ST = Beijing L = Beijing O = Example Inc. OU = IT Department CN = example.com [v3_req] subjectAltName = @alt_names [alt_names] DNS.1 = example.com DNS.2 = www.example.com DNS.3 = test.example.com IP.1 = 127.0.0.1 EOF ) ``` 这个命令利用了进程替换(`<(...)`)来动态生成配置文件,避免了手动创建文件。 生成自签名证书(低版本): ```bash openssl req -x509 -nodes \ -newkey rsa:2048 \ -keyout server.key \ -out server.crt \ -days 365 \ -subj "/C=CN/ST=Beijing/L=Beijing/O=Example Inc./OU=IT Department/CN=example.com" \ -config <(cat <<-EOF [req] distinguished_name = req_distinguished_name req_extensions = v3_req prompt = no [req_distinguished_name] C = CN ST = Beijing L = Beijing O = Example Inc. OU = IT Department CN = example.com [v3_req] subjectAltName = @alt_names [alt_names] DNS.1 = example.com DNS.2 = www.example.com DNS.3 = test.example.com IP.1 = 127.0.0.1 EOF ) ``` 总结: 1. 对于OpenSSL 1.1.1及以上版本,使用`-addext`参数是最简单的方式。 2. 对于低版本,可以使用进程替换(在支持它的shell中,如bash)来动态生成配置文件。 注意:在Windows命令提示符中,进程替换不可用,因此需要单独创建配置文件。 如果你需要为Netty服务器生成证书,请确保SAN中包含服务器使用的域名或IP地址,以避免证书验证错误。 相关问题: 1. 如何验证生成证书是否包含多个SAN? 2. 如何在Java中加载包含多个SAN的证书? 3. 如何将PEM格式的证书转换为PKCS12格式供Java使用?</think># OpenSSL 命令行生成多域名证书(SAN)指南 在生成 OpenSSL 证书时,可以通过命令行直接添加多个域名支持(SAN),无需单独创建配置文件。以下是完整的方法: ## 方法一:OpenSSL 1.1.1+ 使用 `-addext` 参数(推荐) ```bash # 生成私钥 openssl genpkey -algorithm RSA -out server.key -pkeyopt rsa_keygen_bits:2048 # 生成包含多个SAN的证书请求 openssl req -new -key server.key -out server.csr \ -subj "/C=CN/ST=Beijing/L=Beijing/O=Example Inc./OU=IT Department/CN=example.com" \ -addext "subjectAltName = DNS:example.com, DNS:www.example.com, DNS:api.example.com, IP:127.0.0.1" # 生成自签名证书(包含SAN) openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt \ -extfile <(printf "subjectAltName=DNS:example.com,DNS:www.example.com,DNS:api.example.com,IP:127.0.0.1") ``` ## 方法二:兼容所有OpenSSL版本的命令(使用进程替换) ```bash # 生成私钥 openssl genpkey -algorithm RSA -out server.key -pkeyopt rsa_keygen_bits:2048 # 生成证书请求(包含SAN) openssl req -new -key server.key -out server.csr \ -subj "/C=CN/ST=Beijing/L=Beijing/O=Example Inc./OU=IT Department/CN=example.com" \ -config <(cat <<EOF [req] distinguished_name = req_distinguished_name req_extensions = v3_req prompt = no [req_distinguished_name] C = CN ST = Beijing L = Beijing O = Example Inc. OU = IT Department CN = example.com [v3_req] basicConstraints = CA:FALSE keyUsage = nonRepudiation, digitalSignature, keyEncipherment subjectAltName = @alt_names [alt_names] DNS.1 = example.com DNS.2 = www.example.com DNS.3 = api.example.com IP.1 = 127.0.0.1 EOF ) # 生成自签名证书 openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt \ -extensions v3_req -extfile <(cat <<EOF [ v3_req ] basicConstraints = CA:FALSE keyUsage = nonRepudiation, digitalSignature, keyEncipherment subjectAltName = @alt_names [alt_names] DNS.1 = example.com DNS.2 = www.example.com DNS.3 = api.example.com IP.1 = 127.0.0.1 EOF ) ``` ## 验证生成证书 ```bash openssl x509 -in server.crt -text -noout | grep -A 1 "Subject Alternative Name" ``` 输出应包含所有指定的域名IP地址: ``` X509v3 Subject Alternative Name: DNS:example.com, DNS:www.example.com, DNS:api.example.com, IP Address:127.0.0.1 ``` ## 转换为PKCS12格式(供Java使用) ```bash openssl pkcs12 -export -in server.crt -inkey server.key \ -out server.p12 -name server -passout pass:yourpassword ``` ## 关键参数说明 1. **`-addext`**:OpenSSL 1.1.1+ 新增参数,直接添加扩展字段 2. **`-config <(...)`**:进程替换技巧,动态生成配置文件 3. **`subjectAltName`**:SAN扩展字段,支持多种类型: - `DNS`:域名 - `IP`:IP地址 - `email`:邮箱地址 - `URI`:统一资源标识符 4. **通配符支持**: ```bash -addext "subjectAltName = DNS:*.example.com, DNS:*.dev.example.com" ``` ## 常见问题解决 1. **"unknown option -addext" 错误**: ```bash # 检查OpenSSL版本 openssl version # 如果版本低于1.1.1,使用进程替换方法 ``` 2. **Windows系统注意事项**: ```powershell # 使用临时文件代替进程替换 $configContent = @" [req] distinguished_name = req_distinguished_name req_extensions = v3_req prompt = no [req_distinguished_name] C = CN ST = Beijing L = Beijing O = Example Inc. OU = IT Department CN = example.com [v3_req] subjectAltName = @alt_names [alt_names] DNS.1 = example.com DNS.2 = www.example.com DNS.3 = api.example.com IP.1 = 127.0.0.1 "@ $configContent | Out-File -Encoding utf8 openssl.cnf openssl req -new -key server.key -out server.csr -config openssl.cnf ``` 3. **证书生成**: ```bash # 生成CA证书 openssl req -x509 -newkey rsa:2048 -days 365 \ -keyout ca.key -out ca.crt \ -subj "/CN=My Custom CA" # 用CA签署包含SAN的证书 openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key \ -CAcreateserial -out server.crt -days 365 \ -extfile <(printf "subjectAltName=DNS:example.com,DNS:www.example.com") ``` 这些方法允许您在不创建单独配置文件的情况下,通过单个命令生成包含多个SAN条目的证书,适用于各种TLS服务器配置需求[^1][^2][^3][^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值