OpenSSL是为网络通信提供安全及数据完整性的开放源代码软件库包,囊括了主要的密码算法、常用的密钥和证书封装管理功能以及SSL协议。本笔记介绍了OpenSSL命令行的摘要算法、密钥生成与管理、对称加密算法、非对称加密算法、密钥协商算法、签名验签算法等命令的使用方法。以SHA、RSA、AES、ECC、ECDSA、ECDH等为例进行介绍。
文章目录
一、摘要算法
1. 详细使用手册
man openssl-dgst
2. 生成摘要
以SHA256为例。
openssl dgst -SHA256 -hex msg.txt
- -SHA256 使用SHA256哈希算法,支持的摘要算法可以通过
openssl list -digest-algorithms
查看。 - -hex为摘要输出默认选项,输出为编码后、可识别(UTF-8等)的十六进制摘要。
openssl dgst -SHA256 -out dgst.d msg.txt
- 摘要默认输出为编码后的十六进制文件。
- -out <filename> 选项,指定摘要输出文件。
openssl dgst -SHA256 -binary -out dgst.d msg.txt
-
若要后续进一步处理,应使用-binary选项输出二进制。
-
使用hexdump工具查看二进制文件。可以发现二进制与之前生成的十六进制摘要一致。
3. 数字签名
生成签名:
openssl dgst -sha256 -sign rsa.key -out signature.sign msg.txt
- -sign 指定用于生成签名的私钥,无需指定算法,工具从key中识别。
- 签名默认输出为二进制数据。
验证签名:
openssl dgst -sha256 -verify rsa_pub.key -signature signature.sign msg.txt
- -verify指定验签的公钥。
- -signature指定签名文件。
- 输出结果为:“Verified OK” 或 “Verification Failure”
二、对称加密算法
1. 详细使用手册
man openssl-enc
2. 加密
以AES为例
openssl enc -aes-128-cbc -e -a -p -pbkdf2 -in msg.txt -out chiper.enc
- -aes-128-cbc指定加密算法,在man openssl-enc中列出支持的算法。
- -e表示加密
- -a指定加密后的数据进行base64编码,以方便传输。
- -pbkdf2表示使用pbkdf2算法生成密钥,迭代次数由-iter指定,否则使用默认迭代次数。
- -p表示加密后,输出实际使用的盐、密钥和偏移值到标准输出。
在执行加密时,会让输入password,并不是实际加密的密钥。实际加密的密钥是根据输入的password,利用kdf算法(如pbkdf2)生成的。实际密钥和偏移值可以使用
-p
选项,在加密后输出。同时,也可以通过
-K key
指定实际使用的密钥。
在加密的时候会默认加入随机值盐salt,使得每次加密的生成密钥和加密值不一致,增加爆破难度。可以使用
-nosalt
选项不使用盐,通过-p可以发现,password一致时,每次生成的key都一样的。同样的,也可以使用
-S salt
指定使用的盐而不使用随机值。
3. 解密
openssl enc -aes-128-cbc -d -a -p -pbkdf2 -in chiper.enc -out plain.d
- -aes-128-cbc指定解密算法。
- -e表示解密
- -a指定先进行base64解码,再进行解密。
- -pbkdf2表示加密时的密钥使用pbkdf2算法生成。
- -p表示解密后,输出实际使用的盐、密钥和偏移值到标准输出。
三、密钥生成与处理
以RSA为例。
1. 详细使用手册
man openssl-genrsa # RSA key generation
man openssl-genpkey # common key generation for RSA, DSA, DH, EC and so on
man openssl-rsa # RSA key processing
man openssl-pkey # common key processing for RSA, DSA, DH, EC and so on
2. 生成密钥
openssl genrsa -out rsa.pem 1024
- -out <filename> 输出的密钥文件。
- 最后(1024)指明密钥的位数,不得小于512,默认2048。
此处生成的私钥处于明文状态,需对私钥文件进行加密:
openssl genrsa -aes128 -out rsa.pem 1024
- -aes128 指定给密钥加密算法
3. 导出公钥
openssl rsa -in rsa.pem -pubout -out rsa_pub.pem
- -in指定输入的私钥文件。
- -pubout:默认输出为私钥,利用该选项指定输出为公钥。
Ps: -in -out 默认都是私钥,当输入或输出为公钥时,要分别加上-pubin、-pubout。若输入已经加上-pubin时,若输出也为公钥-pubout一般不用加,因为输入为公钥,输出默认也为公钥。
该原则适用于以下所有
openssl rsa
指令。
- -out指定输出公钥文件。
4. 密钥格式转化
默认生成和输入输出都是pem格式,可以进行pem和der格式转化。
# pub key PEM to DER
openssl rsa -pubin -in rsa_pub.pem -outform DER -out rsa_pub.der
# priv key PEM to DER
openssl rsa -in rsa.pem -outform DER -out rsa.der
- -outform 指定输出格式。
- -pubin:默认输入为私钥,利用该选项指定输入为公钥。
5. 查看密钥参数
openssl rsa -in rsa.pem -text -noout
- -text指明输出密钥的组件
- -noout指明不输出编码的密钥
四、非对称密钥算法
以RSA为例。rsautl
在3.0版本被废弃,用pkeyutl
代替。
1. 详细使用手册
man openssl-pkeyutl
man openssl-rsautl # The command rsautl was deprecated in version 3.0. Use 'pkeyutl' instead.
2. 加密
# RSA enc
openssl pkeyutl -encrypt -in msg.txt -pubin -inkey rsa_pub.pem -out rsa_chiper.enc
# RSA enc padding oaep
openssl pkeyutl -encrypt -in msg.txt -pubin -inkey rsa_pub.pem -out rsa_chiper.enc -pkeyopt rsa_padding_mode:oaep -pkeyopt rsa_oaep_md:sha256
- -encrypt 表示加密
- -in 要加密的文件
- -pubin:默认输入私有密钥,表示输入密钥为公钥
- -inkey 指明加密的公钥文件
- -out输出的加密文件
- 可通过-pkeyopt rsa_padding_mode:oaep指明填充模式为oaep
- 可通过-pkeyopt rsa_oaep_md:sha256指明oaep使用的摘要算法为SHA256
3. 解密
# RSA dec
openssl pkeyutl -decrypt -in rsa_chiper.enc -inkey rsa.pem -out rsa_plain.d
# RSA dec padding oaep
openssl pkeyutl -decrypt -in rsa_chiper.enc -inkey rsa.pem -out rsa_plain.d -pkeyopt rsa_padding_mode:oaep -pkeyopt rsa_oaep_md:sha256
- -decrypt 表示解密
- -in 要解密的文件
- -inkey 指明解密的私钥文件
- -out输出的解密文件
- 可通过-pkeyopt rsa_padding_mode:oaep指明填充模式为oaep
- 可通过-pkeyopt rsa_oaep_md:sha256指明oaep使用的摘要算法为SHA256
4. 签名
openssl pkeyutl -sign -inkey rsa.pem -in hash.dgst -out signature.sign
- -sign 表示签名操作
- -inkey 指明签名的私钥
- -in 指明被签名的hash文件(二进制)
- -out 指明签名文件
5. 验签
openssl pkeyutl -verify -pubin -inkey rsa_pub.pem -in hash.dgst -sigfile signature.sign
- -verify 表明验签操作
- -pubin:默认输入私有密钥,表示输入密钥为公钥
- -inkey 指明签名的公钥
- -in 指明被签名的hash文件(二进制)
- -sigfile 指明签名文件
指令校验-sigfile文件是否为-in的签名,直接输出验证结果。
openssl pkeyutl -verifyrecover -hexdump -pubin -inkey rsa_pub.pem -in signature.sign
or
openssl pkeyutl -verifyrecover -pubin -inkey rsa_pub.pem -in signature.sign | hexdump
- -verify 表明验签操作
- -pubin:默认输入私有密钥,表示输入密钥为公钥
- -inkey 指明签名的公钥
- -in 指明签名文件
- -hexdump 显示输出的二进制文件,也可以不使用该选项,管道传输至hexdump解析。
该指令将-in文件恢复,对比可见输出数据和签名前的数据hash.dgst一致。
五、 通用公钥算法指令(ECC为例)
1. 详细使用手册
# common
man openssl-genkey
man openssl-pkey
man openssl-pkeyparam
man openssl-pkeyutl
# EC
man openssl-ec
man openssl-ecparam
pkey、pkeyparam分别是ec和ecparam的通用版本,支持其他公钥算法的密钥和参数处理,而ec和ecparam只支持ec的相关操作。
2. 生成参数
查看支持的椭圆曲线
openssl ecparam -list_curves
- -list_curves 列出支持的椭圆曲线。
选择曲线生成参数
openssl genpkey -genparam -algorithm EC -out ec_param.pem -pkeyopt ec_paramgen_curve:secp256k1 -pkeyopt ec_param_enc:named_curve
or
openssl ecparam -out ec_param_exp.pem -name secp256k1 -param_enc explicit
genpkey
- -genparam指明生成参数
- -algorithm指明公钥算法,参数生成支持DH, DSA和EC
- -out指明输出的参数文件
- -pkeyopt ec_paramgen_curve:secp256k1指定曲线为P-256
- -pkeyopt ec_param_enc:指定参数的编码方式,named_curve 通过曲线名字(OID)编码,explicit通过显式的参数(a, b, G, p, n, h)编码(下节
text
可见区别)
ecparam
- -out指明输出的参数文件
- -name指定参数的编码方式,named_curve 通过曲线名字(OID)编码,explicit通过显式的参数(a, b, G, p, n, h)编码(下节
text
可见区别)
显示曲线参数
openssl ecparam -in ec_param.pem -text
openssl ecparam -in ec_param_exp.pem -text
- -text 显示参数
- -in指定输入参数文件
3. 生成密钥
从参数生成密钥
openssl genpkey -paramfile ec_param.pem -out eckey.pem
- -paramfile 指定输入的参数文件
- -out 指定输出的密钥文件
直接生成密钥
openssl genpkey -algorithm EC -out eckey.pem -pkeyopt ec_paramgen_curve:secp256k1 -pkeyopt ec_param_enc:named_curve
or
openssl ecparam -out ec_key.pem -name secp256k1 -genkey
genpkey
- -genparam指明生成参数
- -algorithm指明公钥算法,密钥生成支持RSA, RSA-PSS, EC, X25519, X448, ED25519和ED448
- -out指明输出的密钥文件
- -pkeyopt ec_paramgen_curve:secp256k1指定曲线为P-256
- -pkeyopt ec_param_enc:指定参数的编码方式,named_curve 通过曲线名字(OID)编码,explicit通过显式的参数编码
ecparam
- -out指明输出的密钥文件
- -name指定参数的编码方式,named_curve 通过曲线名字(OID)编码,explicit通过显式的参数编码
4. 密钥处理
对于EC算法,ec和pkey都可实现以下操作,下以ec为例,pkey可直接替换
输出公钥
openssl ec -in ec_key.pem -pubout -out ec_key_pub.pem
-
-in指定输入的私钥文件。
-
-pubout指定输出为公钥。
-
-out指定输出公钥文件。
私钥文件加密
openssl ec -in ec_key.pem -aes128 -out ec_key.pem
-
-in指定输入的私钥文件。
-
-aes128指定加密算法为aes128。
-
-out指定输出加密私钥文件。
显示密钥参数
openssl ec -in ec_key.pem -text
6. 签名验签ECDSA
# signature
openssl pkeyutl -sign -inkey ec_key.pem -in hash.dgst -out signature.sign
Enter pass phrase for ec_key.pem:
# verify
openssl pkeyutl -verify -pubin -inkey ec_key_pub.pem -in hash.dgst -sigfile signature.sign
Signature Verified Successfully
- 指令与RSA一致。
7. 密钥协商ECDH
openssl pkeyutl -derive -inkey ec_keyA.pem -peerkey ec_key_pubB.pem -out secretA
openssl pkeyutl -derive -inkey ec_keyB.pem -peerkey ec_key_pubA.pem -out secretB
- -derive 表示进行共享密钥导出
- -inkey 指明己方私钥
- -peerkey 指明对方公钥
- -out 输出共享密钥
Ps: 学习笔记分享交流,如有错误欢迎指出。