OpenSSL 命令行脚本示例

文章目录


前言

OpenSSL是一个开源的加密工具包,主要用于实现网络通信的安全传输和数据加密。它解决了互联网上数据传输的机密性、完整性和身份验证问题。

核心实用功能包括:

  1. SSL/TLS协议实现:为网站(HTTPS)、邮件、VPN等提供加密通信通道。
  2. 证书管理:生成、签名和管理数字证书(如用于HTTPS的X.509证书)。
  3. 加密算法库:支持AES、RSA、ECDSA等主流加密算法,用于数据加密和数字签名。
  4. 命令行工具 :通过openssl命令进行证书申请、格式转换、加密解密等操作。

典型应用场景:

  • 网站部署HTTPS
  • 应用程序内加密通信
  • 数字证书签发验证
  • 开发中的安全模块集成

几个最常用、最实用的 OpenSSL 命令行脚本示例

场景一:生成自签名证书(用于本地HTTPS开发)

这是最常见的需求,比如在本地搭建一个测试用的HTTPS网站。

bash 复制代码
#!/bin/bash
# 脚本:生成一个自签名的SSL证书和私钥
# 文件名:generate_self_signed_cert.sh

# 1. 生成一个4096位的RSA私钥,并设置密码保护(可选,这里示例为无密码)
openssl genrsa -out server.key 4096

# 2. 使用上一步的私钥,创建一个证书签名请求(CSR)
# 你需要交互式地输入国家、省份、通用名(域名)等信息
openssl req -new -key server.key -out server.csr -subj "/C=CN/ST=Beijing/L=Beijing/O=MyCompany/CN=localhost"

# 3. 使用自己的私钥对CSR进行自签名,生成有效期为365天的证书
openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt

echo "生成完毕!"
echo "私钥: server.key (务必保密!)"
echo "证书: server.crt (可配置到Web服务器)"

使用bash generate_self_signed_cert.sh, 之后将 server.crtserver.key 配置到 Nginx 或 Apache 即可。


场景二:加密与解密文件

用于安全地传输或存储文件。

bash 复制代码
#!/bin/bash
# 脚本:使用对称加密算法加密/解密一个文件
# 文件名:file_crypto.sh

ACTION=$1 # 传入 'enc' 或 'dec'
FILE=$2  # 文件名

if [ "$ACTION" = "enc" ]; then
    # 使用 AES-256-CBC 算法加密文件,会提示你输入一个密码
    openssl enc -aes-256-cbc -salt -in "$FILE" -out "${FILE}.encrypted"
    echo "文件已加密为: ${FILE}.encrypted"
    echo "请牢记你设置的密码!"

elif [ "$ACTION" = "dec" ]; then
    # 解密一个加密过的文件
    OUTPUT_FILE="${FILE%.encrypted}" # 去掉 .encrypted 后缀
    openssl enc -aes-256-cbc -d -in "$FILE" -out "$OUTPUT_FILE"
    echo "文件已解密为: $OUTPUT_FILE"

else
    echo "用法: $0 [enc|dec] <文件名>"
    echo "示例:"
    echo "  加密: $0 enc my_secret.txt"
    echo "  解密: $0 dec my_secret.txt.encrypted"
fi

使用

  • 加密:bash file_crypto.sh enc myfile.pdf
  • 解密:bash file_crypto.sh dec myfile.pdf.encrypted

场景三:检查远程服务器的SSL证书信息

诊断网站证书是否有效、由谁签发、何时过期。

bash 复制代码
#!/bin/bash
# 脚本:获取并显示一个远程服务器的SSL证书详情
# 文件名:check_ssl_cert.sh

SERVER_NAME=$1
PORT=${2:-443} # 默认检查443端口

if [ -z "$SERVER_NAME" ]; then
    echo "用法: $0 <域名> [端口]"
    echo "示例: $0 github.com"
    echo "示例: $0 smtp.office365.com 587"
    exit 1
fi

echo "正在检查 $SERVER_NAME:$PORT 的SSL证书信息..."
echo "======================================"

# 核心命令:连接服务器,获取证书,并用文本格式输出
openssl s_client -connect "$SERVER_NAME:$PORT" -servername "$SERVER_NAME" < /dev/null 2>/dev/null | openssl x509 -noout -text | grep -A2 -B2 "Issuer:\|Subject:\|Not Before\|Not After\|DNS:"

# 专门提取过期时间
echo ""
echo "=== 证书过期时间 ==="
openssl s_client -connect "$SERVER_NAME:$PORT" -servername "$SERVER_NAME" < /dev/null 2>/dev/null | openssl x509 -noout -dates

使用bash check_ssl_cert.sh www.example.com


场景四:证书格式转换

不同服务器(如Nginx, Apache, Java Keystore, Windows IIS)需要不同格式的证书。

bash 复制代码
#!/bin/bash
# 脚本:将 PEM 格式证书转换为 PFX/P12 格式(常用于Windows或Java)
# 文件名:convert_cert_to_pfx.sh

# 假设你有以下文件(请替换为你的实际文件名)
CERT_FILE="domain.crt"   # 证书文件
KEY_FILE="domain.key"    # 私钥文件
CA_FILE="ca-bundle.crt" # 中间证书链文件(可选,但推荐)
OUTPUT_PFX="domain.pfx"  # 输出的PFX文件名

echo "正在将证书和私钥打包为 $OUTPUT_PFX ..."
echo "过程中会要求你设置一个导出密码,请务必记住!"

# 核心转换命令
openssl pkcs12 -export \
    -out "$OUTPUT_PFX" \
    -inkey "$KEY_FILE" \
    -in "$CERT_FILE" \
    -certfile "$CA_FILE"  # 如果CA_FILE存在则添加证书链

if [ $? -eq 0 ]; then
    echo "转换成功!文件: $OUTPUT_PFX"
else
    echo "转换失败,请检查输入文件是否存在。"
fi

使用 : 将你的证书文件放在同目录,修改脚本开头的文件名变量,然后运行 bash convert_cert_to_pfx.sh

重要提示

  1. 私钥(.key 文件)是最高机密,绝不能泄露。
  2. 自签名证书仅用于测试,公开网站需要从证书颁发机构(如 Let's Encrypt)获取受信任的证书。
  3. 这些脚本是基础示例,生产环境请根据具体需求和安全规范进行调整。

Unix/Linux 管道(pipeline)哲学

keytool 与 openssl 配合使用

命令解析

bash 复制代码
keytool -exportcert -alias testalias -keystore test.keystore | openssl dgst -sha256

各部分的职责:

  1. keytool(Java 工具)

    • 从 Java Keystore (test.keystore) 中提取别名 testalias 的证书
    • 默认以 二进制 DER 格式 输出到标准输出(stdout)
  2. |(管道符)

    • keytool 的标准输出 直接连接openssl 的标准输入(stdin)
    • 无需创建中间临时文件,数据在内存中流动
  3. openssl dgst -sha256

    • 从标准输入读取数据(即证书的二进制内容)
    • 计算其 SHA-256 哈希值
    • 将哈希值以十六进制形式输出

实际应用场景

这是 证书指纹(Certificate Fingerprint) 计算的常见方法,用于:

  • 验证下载的证书是否与官方一致
  • 移动应用中配置 SSL Pinning(证书固定)
  • 快速核对证书的完整性

更多实用管道组合示例

示例1:获取证书的完整信息

bash 复制代码
# 先用keytool导出证书,然后用openssl解析显示
keytool -exportcert -alias myalias -keystore keystore.jks | \
  openssl x509 -inform DER -text

示例2:从证书生成公钥

bash 复制代码
# 提取证书,然后从中导出公钥
keytool -exportcert -alias server -keystore server.jks | \
  openssl x509 -inform DER -pubkey -noout

示例3:验证证书链

bash 复制代码
# 从Java密钥库导出证书,验证其有效性
keytool -exportcert -alias myapp -keystore myapp.jks | \
  openssl x509 -inform DER -dates

为什么用管道?

方式 优点 缺点
管道方式 内存操作,无需磁盘I/O 一行命令完成 无临时文件残留 出错调试稍复杂
临时文件方式 便于分步调试 需要清理临时文件 有磁盘I/O开销
bash 复制代码
# 临时文件方式(等价于管道,但分两步)
keytool -exportcert -alias testalias -keystore test.keystore -file cert.der
openssl dgst -sha256 cert.der

高级管道技巧

1. 多级管道

bash 复制代码
# 提取证书 -> 转为PEM格式 -> 计算指纹 -> 格式美化
keytool -exportcert -alias testalias -keystore test.keystore | \
  openssl x509 -inform DER | \
  openssl x509 -fingerprint -sha256 | \
  cut -d= -f2 | tr -d ':'

2. 与其他工具结合

bash 复制代码
# 将证书指纹与已知指纹对比
KEYTOOL_OUTPUT=$(keytool -exportcert -alias myalias -keystore my.jks | openssl dgst -sha256)
EXPECTED="abc123..."
if [ "$KEYTOOL_OUTPUT" = "SHA256($EXPECTED)" ]; then
    echo "证书指纹匹配!"
fi

3. 网络与管道的结合

bash 复制代码
# 从服务器获取证书 -> 计算指纹 -> 存储
echo | openssl s_client -connect example.com:443 2>/dev/null | \
  openssl x509 -pubkey -noout | \
  openssl pkey -pubin -outform der | \
  openssl dgst -sha256 -binary | \
  openssl base64

命令的完整工作流程

复制代码
┌─────────────────────┐     ┌─────────────────┐     ┌──────────────────────┐
│  keytool 命令        │     │   管道传输      │     │   openssl 命令       │
│  - 读取keystore文件  │────▶│  二进制证书数据  │────▶│  - 计算SHA-256哈希   │
│  - 导出证书          │     │  (在内存中)    │     │  - 输出十六进制结果  │
└─────────────────────┘     └─────────────────┘     └──────────────────────┘

实用建议

  1. 调试管道命令 :可以使用 tee 命令查看中间结果

    bash 复制代码
    keytool -exportcert ... | tee cert.bin | openssl dgst -sha256
  2. 错误处理:在脚本中添加错误检查

    bash 复制代码
    if ! fingerprint=$(keytool ... | openssl dgst -sha256 2>/dev/null); then
        echo "错误:无法计算证书指纹"
        exit 1
    fi
  3. 提高兼容性:明确指定格式

    bash 复制代码
    # 明确指定DER格式,避免openssl自动检测失败
    keytool -exportcert ... | openssl dgst -sha256 -binary

这种管道组合体现了 Unix 哲学的核心思想:"每个程序只做好一件事,通过管道组合完成复杂任务" 。这正是 openssl 能与 keytoolcurlssh 等无数工具无缝协作的原因。

相关推荐
IMPYLH5 小时前
Linux 的 groups 命令
linux·运维·服务器·bash
L_09079 小时前
【Linux】实现简易 shell 程序
linux·bash
廖圣平4 天前
从零开始,福袋直播间脚本研究【八】《策略模式》
开发语言·python·bash·策略模式
西西弗Sisyphus5 天前
Linux Shell 脚本中的 Shebang(#! /bin/bash)是什么
linux·bash·shebang
MarkHD6 天前
RPA工程化实践:重构电商抓取项目——从混乱脚本到模块化、可配置化系统
重构·bash·rpa
晨曦蜗牛6 天前
Windows 上 Claude Code 报错 “requires git-bash“ 的完整解决方案
windows·git·bash
淮北4947 天前
bash下好用的快捷键以及linux常用指令
linux·开发语言·ubuntu·bash
JobDocLS9 天前
Bash调试方法
开发语言·bash
dys_Codemonkey10 天前
ROS 2 环境配置与 Shell 配置文件详解(zsh/bash)ROS 2 多工作空间规范配置
开发语言·chrome·bash