You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何通过Python脚本实现OpenSSL自签名SSL证书无交互自动生成?

我来帮你搞定这个自动化生成自签名SSL证书的问题!你遇到的OpenSSL交互输入难题,其实用自带参数或配置文件就能轻松解决,下面分三种方案给你详细说明:

方案一:直接修改命令行参数,彻底跳过交互

这是最直接的解决方案,不需要额外配置,给每个OpenSSL命令加对应参数就能避免输入提示:

  1. 生成带密码的RSA私钥:用-passout参数直接指定密码,完全不用交互输入
openssl genrsa -des3 -out server.key -passout pass:your_secure_password 1024
  1. 生成CSR(证书签名请求):用-subj参数一次性填完所有身份信息,跳过问答式输入
openssl req -new -key server.key -out server.csr -subj "/C=CN/ST=Beijing/L=Beijing/O=YourCompany/OU=TechDept/CN=your.domain.com" -passin pass:your_secure_password

这里的-passin是用来解锁带密码的私钥,必须和之前设置的密码一致。

  1. 移除私钥的密码(可选,如果你不想后续用证书时每次输密码)
cp server.key server.key.org
openssl rsa -in server.key.org -out server.key -passin pass:your_secure_password
  1. 生成自签名证书
openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt

把这些命令整合到你的脚本里,cron运行时就完全不会有任何交互了。

方案二:修复你的Python脚本,实现自动化

你之前用Popenstdin失败,大概率是Windows下的换行符问题(Windows用\r\n而非\n),不过更可靠的方式是直接用OpenSSL的-passout参数,避免依赖stdin输入:

from subprocess import Popen, PIPE

# 生成带密码的私钥
p = Popen(
    ['openssl', 'genrsa', '-des3', '-out', 'server.key', '-passout', 'pass:your_secure_password', '1024'],
    stdout=PIPE,
    stdin=PIPE,
    stderr=STDOUT
)
output, _ = p.communicate()
print(output.decode('utf-8'))

# 生成CSR
p = Popen(
    ['openssl', 'req', '-new', '-key', 'server.key', '-out', 'server.csr', 
     '-subj', '/C=CN/ST=Beijing/L=Beijing/O=YourCompany/OU=TechDept/CN=your.domain.com',
     '-passin', 'pass:your_secure_password'],
    stdout=PIPE,
    stdin=PIPE,
    stderr=STDOUT
)
output, _ = p.communicate()
print(output.decode('utf-8'))

# 移除私钥密码
p = Popen(
    ['openssl', 'rsa', '-in', 'server.key.org', '-out', 'server.key', '-passin', 'pass:your_secure_password'],
    stdout=PIPE,
    stdin=PIPE,
    stderr=STDOUT
)
output, _ = p.communicate()
print(output.decode('utf-8'))

# 生成自签名证书
p = Popen(
    ['openssl', 'x509', '-req', '-days', '365', '-in', 'server.csr', '-signkey', 'server.key', '-out', 'server.crt'],
    stdout=PIPE,
    stdin=PIPE,
    stderr=STDOUT
)
output, _ = p.communicate()
print(output.decode('utf-8'))

要是你坚持想用stdin传密码,可以把input改成b'your_secure_password\r\nyour_secure_password\r\n'试试,但还是推荐用参数方式,兼容性更好。

方案三:使用openssl.cnf配置文件,统一管理参数

这种方式适合需要重复生成证书、或者想要统一配置字段的场景,先创建一个openssl.cnf文件:

[req]
prompt = no                  # 关闭交互提示
default_bits = 1024          # 私钥位数
default_md = sha256          # 哈希算法
distinguished_name = dn      # 指定DN配置段
input_password = your_secure_password  # 私钥输入密码
output_password = your_secure_password # 私钥输出密码

[dn]
C = CN                       # 国家代码
ST = Beijing                 # 省份
L = Beijing                  # 城市
O = YourCompany              # 组织名称
OU = TechDept                # 部门名称
CN = your.domain.com         # 域名/Common Name

然后用以下命令执行:

# 生成带密码的私钥
openssl genrsa -des3 -out server.key -config openssl.cnf 1024

# 生成CSR
openssl req -new -key server.key -out server.csr -config openssl.cnf

# 移除私钥密码
cp server.key server.key.org
openssl rsa -in server.key.org -out server.key -passin pass:your_secure_password

# 生成自签名证书
openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt

所有配置都集中在文件里,修改起来更方便,也避免了命令行里堆太多参数。

补充:如果是Windows下用任务计划程序替代cron,要确保OpenSSL的路径在系统环境变量里,或者在脚本里写绝对路径(比如C:\OpenSSL-win64\bin\openssl.exe)。

内容的提问来源于stack exchange,提问作者user707779

火山引擎 最新活动