OpenSSL 介绍(3)--对称加密
本文主要介绍如何使用 OpenSSL 来进行对称加解密,文中所使用到的软件版本:OpenSSL 1.1.1s、CentOS 7.9.2009。
1、对称加密算法
对称加密(也叫私钥加密)指加密和解密使用相同密钥的加密算法。有时又叫传统密码算法,就是加密密钥能够从解密密钥中推算出来,同时解密密钥也可以从加密密钥中推算出来。而在大多数的对称算法中,加密密钥和解密密钥是相同的,所以也称这种加密算法为秘密密钥算法或单密钥算法。它要求发送方和接收方在安全通信之前,商定一个密钥。对称算法的安全性依赖于密钥,泄漏密钥就意味着任何人都可以对他们发送或接收的消息解密,所以密钥的保密性对通信的安全性至关重要。
对称加密算法主要有四种加密模式:
2、用法
可以使用 OpenSSL 来进行对称加解密,通过 openssl enc -help 命令查看用法:
shell> /home/mongo/soft/openssl-1.1.1s/bin/openssl enc -help Usage: enc [options] Valid options are: -help Display this summary -list List ciphers -ciphers Alias for -list -in infile Input file -out outfile Output file -pass val Passphrase source -e Encrypt -d Decrypt -p Print the iv/key -P Print the iv/key and exit -v Verbose output -nopad Disable standard block padding -salt Use salt in the KDF (default) -nosalt Do not use salt in the KDF -debug Print debug info -a Base64 encode/decode, depending on encryption flag -base64 Same as option -a -A Used with -[base64|a] to specify base64 buffer as a single line -bufsize val Buffer size -k val Passphrase -kfile infile Read passphrase from file -K val Raw key, in hex -S val Salt, in hex -iv val IV in hex -md val Use specified digest to create a key from the passphrase -iter +int Specify the iteration count and force use of PBKDF2 -pbkdf2 Use password-based key derivation function 2 -none Don't encrypt -* Any supported cipher -rand val Load the file(s) into the random number generator -writerand outfile Write random data to the specified file -engine val Use engine, possibly a hardware device
参数说明:
参数 | 说明 |
-in infile | 指定输入文件 |
-out outfile | 指定输出文件 |
-pass val | 指定密码的输入方式:命令行输入(pass)、文件输入(file)、环境变量输入(var)、文件描述符输入(fd)、标准输入(stdin)。默认是标准输入。 |
-e | 加密 |
-d | 解密 |
-P | 打印偏移量iv和密钥key,不进行加解密操作 |
-p | 打印偏移量iv和密钥key |
-a,-base64 | 加密时结束用base64编码,解密时输入先用base64解密 |
-S | 指定 salt 值,而不是随机生成;hex 格式 |
-pbkdf2 | 使用第二版本的基于密码生成密钥的函数 |
-* | 指定算法,可以使用 openssl enc -list 查看支持的算法 |
3、查看支持的算法
可以使用 openssl enc -list 查看当前版本 OpenSSL 支持的对称加密算法:
shell> /home/mongo/soft/openssl-1.1.1s/bin/openssl enc -list Supported ciphers: -aes-128-cbc -aes-128-cfb -aes-128-cfb1 -aes-128-cfb8 -aes-128-ctr -aes-128-ecb -aes-128-ofb -aes-192-cbc -aes-192-cfb -aes-192-cfb1 -aes-192-cfb8 -aes-192-ctr -aes-192-ecb -aes-192-ofb -aes-256-cbc -aes-256-cfb -aes-256-cfb1 -aes-256-cfb8 -aes-256-ctr -aes-256-ecb -aes-256-ofb -aes128 -aes128-wrap -aes192 -aes192-wrap -aes256 -aes256-wrap -aria-128-cbc -aria-128-cfb -aria-128-cfb1 -aria-128-cfb8 -aria-128-ctr -aria-128-ecb -aria-128-ofb -aria-192-cbc -aria-192-cfb -aria-192-cfb1 -aria-192-cfb8 -aria-192-ctr -aria-192-ecb -aria-192-ofb -aria-256-cbc -aria-256-cfb -aria-256-cfb1 -aria-256-cfb8 -aria-256-ctr -aria-256-ecb -aria-256-ofb -aria128 -aria192 -aria256 -bf -bf-cbc -bf-cfb -bf-ecb -bf-ofb -blowfish -camellia-128-cbc -camellia-128-cfb -camellia-128-cfb1 -camellia-128-cfb8 -camellia-128-ctr -camellia-128-ecb -camellia-128-ofb -camellia-192-cbc -camellia-192-cfb -camellia-192-cfb1 -camellia-192-cfb8 -camellia-192-ctr -camellia-192-ecb -camellia-192-ofb -camellia-256-cbc -camellia-256-cfb -camellia-256-cfb1 -camellia-256-cfb8 -camellia-256-ctr -camellia-256-ecb -camellia-256-ofb -camellia128 -camellia192 -camellia256 -cast -cast-cbc -cast5-cbc -cast5-cfb -cast5-ecb -cast5-ofb -chacha20 -des -des-cbc -des-cfb -des-cfb1 -des-cfb8 -des-ecb -des-ede -des-ede-cbc -des-ede-cfb -des-ede-ecb -des-ede-ofb -des-ede3 -des-ede3-cbc -des-ede3-cfb -des-ede3-cfb1 -des-ede3-cfb8 -des-ede3-ecb -des-ede3-ofb -des-ofb -des3 -des3-wrap -desx -desx-cbc -id-aes128-wrap -id-aes128-wrap-pad -id-aes192-wrap -id-aes192-wrap-pad -id-aes256-wrap -id-aes256-wrap-pad -id-smime-alg-CMS3DESwrap -idea -idea-cbc -idea-cfb -idea-ecb -idea-ofb -rc2 -rc2-128 -rc2-40 -rc2-40-cbc -rc2-64 -rc2-64-cbc -rc2-cbc -rc2-cfb -rc2-ecb -rc2-ofb -rc4 -rc4-40 -seed -seed-cbc -seed-cfb -seed-ecb -seed-ofb -sm4 -sm4-cbc -sm4-cfb -sm4-ctr -sm4-ecb -sm4-ofb
算法名称中包含了密钥位数及模式,OpenSSL 默认使用 PKCS7Padding 的填充方式。
4、具体使用
4.1、使用 aes-128-cbc 算法加密
shell> echo -n 123456|/home/mongo/soft/openssl-1.1.1s/bin/openssl enc -e -aes-128-cbc -a -p -pbkdf2 -pass pass:abc
salt=5BD68E48B20CADF8
key=D66105C0AE7324FF0D3F9424AC222120
iv =0A03ECE1334289FBB5DBBBC556AA6CD9
U2FsdGVkX19b1o5Isgyt+AtQPniEdSStNGYJJQqPWQY=
OpenSSL 通过用户输入的密码及一个随机的 salt 来生成 key 和 iv,命令执行的生成的结果会包含 salt 值,所以会跟其他加密工具得到的结果不一致;把结果 "U2FsdGVkX19b1o5Isgyt+AtQPniEdSStNGYJJQqPWQY=" 转换为 hex 格式值为:"53616C7465645F5F5BD68E48B20CADF80B503E78847524AD346609250A8F5906",紫色部分是固定的字符串 ”Salted__“,中间红色的部分为 salt 值,最后蓝色的部分是真正的加密结果。
可以通过 -S 来指定 salt 值,这样每次输出的 slat、key、iv 值都是一样的。
该标准命令等效于如下的加解密命令:
echo -n 123456|/home/mongo/soft/openssl-1.1.1s/bin/openssl aes-128-cbc -e -a -p -pbkdf2 -pass pass:abc
4.2、使用 aes-128-cbc 算法解密
echo U2FsdGVkX19b1o5Isgyt+AtQPniEdSStNGYJJQqPWQY= | /home/mongo/soft/openssl-1.1.1s/bin/openssl enc -d -aes-128-cbc -a -p -pbkdf2 -pass pass:abc
4.3、使用文件作为输入
新建文件 a.txt,在文件中输入内容:
123456
使用 a.txt 作为输入:
shell> /home/mongo/soft/openssl-1.1.1s/bin/openssl enc -e -aes-128-cbc -a -p -pbkdf2 -pass pass:abc -S 5BD68E48B20CADF8 -in a.txt salt=5BD68E48B20CADF8 key=D66105C0AE7324FF0D3F9424AC222120 iv =0A03ECE1334289FBB5DBBBC556AA6CD9 U2FsdGVkX19b1o5Isgyt+PY1unvJCsuD7lZxfV9YQxk=
注:标准输入(结束方法:先输入回车,然后输入 ctrl+D)会把换行符也带入计算;使用文件输入时,也会在文件内容最后增加换行作为 OpenSSL 的计算输入;这会导致计算结果(去除结果中 salt 部分)与其他加密工具(如:Java)的计算结果不一致,所以使用 echo -n 来去除换行。