前言
SSL是Secure Sockets Layer(安全套接层协议)的缩写,可以在Internet上提供秘密性传输。Netscape公司在推出第一个Web浏览器的同时,提出了SSL协议标准。其目标是保证两个应用间通信的保密性和可靠性,可在服务器端和用户端同时实现支持。已经成为Internet上保密通讯的工业标准。
SSL能使用户/服务器应用之间的通信不被攻击者窃听,并且始终对服务器进行认证,还可选择对用户进行认证。SSL协议要求建立在可靠的传输层协议(TCP)之上。SSL协议的优势在于它是与应用层协议独立无关的,高层的应用层协议(例如:HTTP,FTP,TELNET等)能透明地建立于SSL协议之上。SSL协议在应用层协议通信之前就已经完成加密算法、通信密钥的协商及服务器认证工作。在此之后应用层协议所传送的数据都会被加密,从而保证通信的私密性。
一、简介
在计算机网络上,OpenSSL是一个开放源代码的软件库包,应用程序可以使用这个包来进行安全通信,避免窃听,同时确认另一端连接者的身份。这个包广泛被应用在互联网的网页服务器上
OpenSSL整个软件包大概可以分成三个主要的功能部分:SSL协议库、应用程序以及密码算法库。OpenSSL的目录结构自然也是围绕这三个功能部分进行规划的。
二、基础使用示例
2.1. 基础
检查版本
$ openssl version -a
它在使用四个 CPU 内核并测试 RSA 算法的系统上运行速度有多快
$ openssl speed -multi 4 rsa
获得基本帮助
$ openssl help
生成 10 个随机字节并将它们显示在屏幕上
$ openssl rand -hex 10
2.2. 编码/解码
使用 Base64 编码文件
$ openssl base64 -in file.txt
使用 Base64 编码一些文本
$ echo -n "test text" | openssl base64
Base64 解码一个文件并输出到另一个文件
$ openssl base64 -d -in encoded.data -out decoded.data
2.3. 使用哈希
列出可用的摘要算法
$ openssl list -digest-algorithms
使用 SHA256 散列文件
$ openssl dgst -sha256 file.txt
使用 SHA256 散列文件及其二进制形式的输出(无输出十六进制编码) 没有 ASCII 或编码字符将打印到控制台,只有纯字节
$ openssl dgst -binary -sha256 file.data
使用 SHA3-512 的哈希文本
$ echo -n "some text" | openssl dgst -sha3-512
创建 HMAC - 使用特定密钥(以字节为单位)的文件的 SHA384
$ openssl dgst -SHA384 -mac HMAC -macopt hexkey:369bd7d655 file.data
创建 HMAC - 一些文本的 SHA512
$ echo -n "some text" | openssl dgst -mac HMAC -macopt hexkey:369bd7d655 -sha512
2.4. 对称加密
列出所有支持的对称加密密码
$ openssl enc -list
使用提供的 ASCII 编码密码和 AES-128-ECB 算法加密文件
$ openssl enc -aes-128-ecb -in cleartext.file -out ciphertext.file -pass pass:thisisthepassword
使用 AES-256-CBC 和密钥文件解密文件
$ openssl enc -d -aes-256-cbc -in ciphertext.file -out cleartext.file -pass file:./key.file
使用以十六进制数字形式提供的特定加密密钥 (K) 加密文件
$ openssl enc -aes-128-ecb -in cleartext.file -out ciphertext.file -K 1881807b2d1b3d22f14e9ec52563d981 -nosalt
使用指定的加密密钥(K:256 位)和初始化向量(iv:128 位)在 CBC 块密码模式下使用 ARIA 256 加密文件
$ openssl enc -aria-256-cbc -in cleartext.file -out ciphertext.file -K f92d2e986b7a2a01683b4c40d0cbcf6feaa669ef2bb5ec3a25ce85d9548291c1 -iv 470bc29762496046882b61ecee68e07c -nosalt
使用提供的密钥和 iv 在 COUNTER 块密码模式下使用 Camellia 192 算法加密文件
$ openssl enc -camellia-192-ctr -in cleartext.file -out ciphertext.file -K 6c7a1b3487d28d3bf444186d7c529b48d67dd6206c7a1b34 -iv 470bc29762496046882b61ecee68e07c
2.5. 非对称加密
列出可用的椭圆曲线
$ openssl ecparam -list_curves
创建 4096 位 RSA 公私密钥对
$ openssl genrsa -out pub_priv.key 4096
显示详细的私钥信息
$ openssl rsa -text -in pub_priv.key -noout
使用 AES-256 算法加密公私钥对
$ openssl rsa -in pub_priv.key -out encrypted.key -aes256
删除密钥文件加密并将它们保存到另一个文件
$ openssl rsa -in encrypted.key -out cleartext.key
将公私钥对文件的公钥复制到另一个文件中
$ openssl rsa -in pub_priv.key -pubout -out pubkey.key
使用 RSA 公钥加密文件
$ openssl rsautl -encrypt -inkey pubkey.key -pubin -in cleartext.file -out ciphertext.file
使用 RSA 私钥解密文件
$ openssl rsautl -decrypt -inkey pub_priv.key -in ciphertext.file -out decrypted.file
使用 P-224 椭圆曲线创建私钥
$ openssl ecparam -name secp224k1 -genkey -out ecpriv.key
使用 3DES 算法加密私钥
$ openssl ec -in ecP384priv.key -des3 -out ecP384priv_enc.key
2.6. 数字签名
为私钥生成 DSA 参数。 2048 位长度
$ openssl dsaparam -out dsaparam.pem 2048
生成用于签署文档的 DSA 公私密钥并使用 AES128 算法对其进行保护
$ openssl gendsa -out dsaprivatekey.pem -aes-128-cbc dsaparam.pem
将DSA公私钥文件的公钥复制到另一个文件中
$ openssl dsa -in dsaprivatekey.pem -pubout -out dsapublickey.pem
打印出 DSA 密钥对文件的内容
$ openssl dsa -in dsaprivatekey.pem -text -noout
使用 RSA 私钥对文件的 sha-256 哈希进行签名
$ openssl dgst -sha256 -sign rsakey.key -out signature.data document.pdf
使用公钥验证 SHA-256 文件签名
$ openssl dgst -sha256 -verify publickey.pem -signature signature.data original.file
使用 DSA 私钥对文件的 sha3-512 哈希进行签名
$ openssl pkeyutl -sign -pkeyopt digest:sha3-512 -in document.docx -inkey dsaprivatekey.pem -out signature.data
验证 DSA 签名
$ openssl pkeyutl -verify -sigfile dsasignature.data -inkey dsakey.pem -in document.docx
使用 P-384 椭圆曲线创建私钥
$ openssl ecparam -name secp384r1 -genkey -out ecP384priv.key
使用3DES算法加密私钥
$ openssl ec -in ecP384priv.key -des3 -out ecP384priv_enc.key
使用带有生成密钥的椭圆曲线对 PDF 文件进行签名
$ openssl pkeyutl -sign -inkey ecP384priv_enc.key -pkeyopt digest:sha3-512 -in document.pdf -out signature.data
验证文件的签名。 如果没问题,您必须收到"签名验证成功"
$ openssl pkeyutl -verify -in document.pdf -sigfile signature.data -inkey ecP384priv_enc.key
2.7. 数字证书
生成 CSR 文件和 4096 位 RSA 密钥对
$ openssl req -newkey rsa:4096 -keyout private.key -out request.csr
显示证书签名请求 ( CSR ) 内容
$ openssl req -text -noout -in request.csr
显示 CSR 文件中包含的公钥
$ openssl req -pubkey -noout -in request.csr
使用现有私钥创建证书签名请求 ( CSR )。 当需要在不更改私钥的情况下更新公共数字证书时,这会很有用
$ openssl req -new -key private.key -out request.csr
创建 EC P384 曲线参数文件以在下一步中使用椭圆曲线生成 CSR
$ openssl genpkey -genparam -algorithm EC -out EC_params.pem -pkeyopt ec_paramgen_curve:secp384r1 -pkeyopt ec_param_enc:named_curve
使用在上一步中创建的椭圆曲线 P384 参数文件创建 CSR 文件。 而不是使用 RSA 密钥。
$ openssl req -newkey ec:EC_params.pem -keyout EC_P384_priv.key -out EC_request.csr
创建自签名证书,新的 2048 位 RSA 密钥对,有效期为6个月
$ openssl req -newkey rsa:2048 -nodes -keyout priv.key -x509 -days 180 -out cert.crt
使用 CSR 文件和用于签名的私钥创建并签署新证书(前提需要准备好 openssl.cnf 文件)
$ openssl ca -in request.csr -out certificate.crt -config ./CA/config/openssl.cnf
显示PEM格式证书信息
$ openssl x509 -text -noout -in cert.crt
以 Abstract Sintax Notation One (ASN.1) 显示证书信息
$ openssl asn1parse -in cert.crt
提取证书的公钥
$ openssl x509 -pubkey -noout -in cert.crt
在证书中提取公钥的模数
$ openssl x509 -modulus -noout -in cert.crt
从 HTTPS/TLS 连接中提取域证书
$ openssl s_client -connect domain.com:443 | openssl x509 -out certificate.crt
将证书从 PEM 格式转换为 DER 格式
$ openssl x509 -inform PEM -outform DER -in cert.crt -out cert.der
检查证书公钥是否与私钥和请求文件匹配。 每个文件一步。 必须在输出哈希中匹配
$ openssl x509 -modulus -in certificate.crt -noout | openssl dgst -sha256
$ openssl rsa -modulus -in private.key -noout | openssl dgst -sha256
$ openssl req -modulus -in request.csr -noout | openssl dgst -sha256
2.8. 个人安全环境 (PSE)
将证书从 PEM (base64) 格式转换为 DER(二进制)格式
$ openssl x509 -in certificate.pem -outform DER -out certificate.der
将证书和私钥插入 PKCS #12 格式文件。 这些文件可以导入到 Windows 证书管理器或 Java Key Store (jks) 文件中
$ openssl pkcs12 -export -out cert_key.p12 -inkey private.key -in certificate.crt
显示 PKCS #12 文件的内容
$ openssl pkcs12 -in cert_key.p12
将 .p12 文件转换为 Java Key Store。 此命令使用 java keytool 而不是 openssl。
keytool -importkeystore -destkeystore javakeystore.jks -srckeystore cert_key.p12 -srcstoretype pkcs12
将 PEM 证书转换为 PKCS #7 格式
$ openssl crl2pkcs7 -nocrl -certfile certificate.crt -out cert.p7b
将 PKCS #7 文件从 PEM 转换为 DER
$ openssl pkcs7 -in cert.p7b -outform DER -out p7.der
2.9. 查看 PEM 编码证书
使用具有证书扩展名的命令将 cert.xxx 替换为证书名称
$ openssl x509 -in cert.pem -text -noout
$ openssl x509 -in cert.cer -text -noout
$ openssl x509 -in cert.crt -text -noout
2.10. 查看 DER 编码证书
$ openssl x509 -in certificate.der -inform der -text -noout
三、转换示例
3.1. OpenSSL 转换 PEM
将 PEM 转换为 DER
$ openssl x509 -outform der -in certificate.pem -out certificate.der
将 PEM 转换为 P7B
$ openssl crl2pkcs7 -nocrl -certfile certificate.cer -out certificate.p7b -certfile CACert.cer
将 PEM 转换为 PFX
$ openssl pkcs12 -export -out certificate.pfx -inkey privateKey.key -in certificate.crt -certfile CACert.crt
3.2. OpenSSL 转换 DER
将 DER 转换为 PEM
$ openssl x509 -inform der -in certificate.cer -out certificate.pem
3.3. OpenSSL 转换 PFX
将 PFX 转换为 PEM
$ openssl pkcs12 -in certificate.pfx -out certificate.cer -nodes
3.4. OpenSSL 转换 P7B
将 P7B 转换为 PEM
$ openssl pkcs7 -print_certs -in certificate.p7b -out certificate.cer
将 P7B 转换成 PFX
$ openssl pkcs7 -print_certs -in certificate.p7b -out certificate.cer
$ openssl pkcs12 -export -in certificate.cer -inkey privateKey.key -out certificate.pfx -certfile CACert.cer
四、校验
在建立 SSL/TLS 连接之前,客户端需要确保收到的证书有效。为了做到这一点,客户端不仅要验证其公钥的真实性,还要验证与之相关的其他元数据(重要):
- **签名验证:**这确保了证书没有以任何方式被更改;
- **证书尚未过期:**当证书由 CA 颁发时,它会指定一个到期日期;
- **证书主题与主机名匹配:**证书是为特定服务器颁发的。因此,证书主题名称需要与客户端尝试连接的 URL 相匹配;
- **它没有被撤销:**有时证书可以在任何需要的情况下被其颁发者撤销(例如,关联的私钥已被公开,因此证书无效);
- **它由受信任的 CA 签名:**为了证明证书的真实性,我们需要获取 CA 证书并验证其可信度。然而在 PKI 中有一个信任链的概念,因此 CA 证书可能是由另一个 CA 颁发的。因此我们需要获得另一个 CA 的证书并验证它。依此类推......因此,为了信任证书,我们需要一直导航到根 CA。最后,如果我们信任根 CA,可以肯定地说我们信任整个链。
OpenSSL官网:https://www.openssl.org/