# 前言
一篇简单的 OpenSSL 对称加密使用经验,偶尔更新。
# 获取帮助
openssl enc -h |
输入如下:
Usage: enc [options] | |
General options: | |
-help Display this summary | |
-list List ciphers | |
-ciphers Alias for -list | |
-e Encrypt | |
-d Decrypt | |
-p Print the iv/key | |
-P Print the iv/key and exit | |
-engine val Use engine, possibly a hardware device | |
Input options: | |
-in infile Input file | |
-k val Passphrase | |
-kfile infile Read passphrase from file | |
Output options: | |
-out outfile Output file | |
-pass val Passphrase source | |
-v Verbose output | |
-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 | |
Encryption options: | |
-nopad Disable standard block padding | |
-salt Use salt in the KDF (default) | |
-nosalt Do not use salt in the KDF | |
-debug Print debug info | |
-bufsize val Buffer size | |
-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 the use of PBKDF2 | |
Default: 10000 | |
-pbkdf2 Use password-based key derivation function 2 (PBKDF2) | |
Use -iter to change the iteration count from 10000 | |
-none Don't encrypt | |
-* Any supported cipher | |
Random state options: | |
-rand val Load the given file(s) into the random number generator | |
-writerand outfile Write random data to the specified file | |
Provider options: | |
-provider-path val Provider load path (must be before 'provider' argument if required) | |
-provider val Provider to load (can be specified multiple times) | |
-propquery val Property query used when fetching algorithms |
# 列出支持的加密算法
可以通过 -list
或 -ciphers
参数来列出当前版本 OpenSSL 支持的对称加密算法:
openssl enc -list |
或:
openssl enc -ciphers |
个人使用的 OpenSSL 版本是 3.1.2,它的输出如下:
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 |
# 对称加密算法命名规则的简单介绍
# 可变密钥长度 分组加密算法
一个可变密钥长度的分组加密算法参数通常由三部分组成,对称加密算法 - 密钥长度 - 分组密码工作模式。
举个例子: AES-128-CTR
AES:对称加密算法 为 高级加密标准(Advanced Encryption Standard,AES),它支持 128 位、192 位和 256 位的密钥长度
128:密钥长度 指定为 128 位
CTR:分组密码工作模式 是 计数器模式(Counter Mode, CTR)
# 固定密钥长度 分组加密算法
一个固定密钥长度的分组加密算法参数通常由两部分组成,对称加密算法 - 分组密码工作模式。
举个例子: SM4-CFB
SM4:对称加密算法 为 商密 - 4,它的 密钥长度默认固定为 128 位
CFB:分组密码工作模式 是 密文反馈模式(Cipher FeedBack,CFB)
# 流密码
一个流密码的参数通常就是对称加密算法本身:对称加密算法。
举个例子: Chacha20
Chacha20:对称加密算法 为 Chacha20
# 默认 ECB 模式
当使用分组密码对称加密算法时不指定分组密码工作模式,OpenSSL 将会默认使用 ECB 模式 对文件进行加密。
举个例子: BF
BF
:对称加密算法 为 Blowfish,默认分组密码工作模式是 电子密码本模式(Electronic CodeBlock),注意,这一模式是不安全的。
# 对称加密算法 简单介绍
# AES
高级加密标准(Advanced Encryption Standard,AES),NIST 标准,原型是 Rjindael,属于 SPN 密码。
目前世界上最流行的加密算法,具有高度的安全性、高度的兼容性、强大的性能和广泛的硬件加速支持,是绝大多数情况下对称加密算法的首选。密文分组 128 位,密钥长度可选 128 位,192 位或 256 位,对应的 SPN 迭代轮次分别为 10 轮、12 轮与 14 轮。
# ARIA
ARIA 是韩国密码学研究者基于 AES 修改而来的一种 SPN 密码,原型是 AES。
韩国用于取代 AES 而设计的加密算法,具有高度安全性和较好的性能,密文分组 128 位,密钥长度可选 128 位,192 位或 256 位,对应的 SPN 迭代轮次分别是 12 轮、14 轮和 16 轮。
# BF(Blowfish)
Blowfish 是 Bruce Schneier 设计的一种 Feistel 密码。
一个相对较老的对称加密算法,密文分组 64 位,密钥长度可选 32-448 位,迭代固定 16 轮。目前仍然具有能够接受的安全性,最优的密文分析只能破解 4 轮 BF,或将 14 轮 BF 与伪随机序列区分开来。但由于密文分组仅有 64 位,研究表明可能存在生日攻击问题。作者 Bruce Schneier 本人建议使用 TwoFish 进行替代。
# Camellia
卡梅利亚(Camellia)是日本 NTT 和 MEC 设计的一款 Feistel 加密算法,其计算量和安全性基本与 AES 相当,名称意为 “山茶”。
一个常见的加密算法,具有高度的安全性、较为广泛的支持、强大的性能,是 AES 的一种替代算法。密文分组 128 位,密钥长度可选 128 位、192 位或 256 位,对应 Feistel 迭代轮次分别为 18 轮,24 轮与 24 轮。
# CAST / CAST5 / CAST-128
CAST 是 Carlisle Adams 和 Stafford Tavares 设计的一款 Feistel 密码,在加拿大常用。
CAST5 的密文分组为 64 位,密钥长度 40-128 位,步长 8 位。80 位以下采用 12 轮迭代,80 位及以上采用 16 轮迭代。被 GPG,PGP 和 OpenSSL 等支持。
# Chacha20
Chacha20 是 Daniel Julius Bernstein 设计的一种流密码算法,是 Salsa20 的改进版本。
Chacha20 采用 128 位或 256 位密钥,ARX 结构,512 位状态位和 20 轮重复,具有高度的安全性。由于 Chacha20 是流密码算法,因此具有低延迟、高性能、算力需求低的优点,适合在移动设备上、ARM 架构处理器与嵌入式设备上使用。常常与 Poly1305 校验码一同使用。
# DES
数据加密标准(Data Encryption Standard, DES),上古加密算法,上世纪 70 年代由 DES 开发,已经过时。
DES 采用 56 位密钥和 64 位密文分组,Feistel 结构 16 轮迭代。在目前的算力下,蛮力攻击(穷举法)攻破 DES 已经成为可能。线性分析和选择明文攻击均能有效削弱 DES 的安全性。
# DES-EDE / DES3 (3DES)
三重数据加密标准(Triple Data Encryption Standard, 3DES)或 DES-EDE(Data Encryption Standard - Encryption Decryption Encryption)是对 DES 的加强,通过三个使用不同密钥的 DES 分别对原始数据进行加密、解密、加密得到密文(密钥选项 1),将密钥空间扩展到 2168,但由于中途相遇攻击,其安全性实际为 2112。
当然,也存在 K2 = K1(密钥选项 2)和 K3 = K2 = K1(密钥选项 3)的 3DES 版本。其中,根据 NIST 的评估,密钥选项 2 的有效安全性仅有约 280,而密钥选项 3 明显不合理,第二轮解密和第一轮加密直接抵消,因此相当于 DES。密钥选项 2 与密钥选项 3 均已经弃用。目前的 3DES 或 DES-EDE 默认使用密钥选项 1。
3DES 对于目前的算力和密码分析手段仍然属于安全的,但是其性能和理论安全性仍然弱于 AES。其主要优势在于能与支持 DES 的老式通信系统兼容。如有可能,应尽量升级到 AES。
# DESX
使用 64 位密钥的 DES,其中仍然是 56 位用于加密,8 位用于校验。不推荐。
# IDEA
国际数据加密算法(International Data Encryption Algorithm,IDEA),最早称为改良建议加密标准(Improved Proposed Encryption Standard,IPES),是 1991 年提出的一种 Feistel 密码。
IDEA 的密文分组长度为 64 位,密钥长度为 128 位,迭代轮次为 8.5。目前 IDEA 被认为是一种不再安全的加密算法,尽管目前最优的攻击方式复杂度仍然来到 2126.1,超过了目前的常规算力破解能力。(资料来源:维基百科)
# RC2 / ARC2
RC2(Rivest Cipher 2)是 Ron Rivest 设计的基于不平衡 Feistel 结构的分组加密算法,目前已经过时,面对相关密钥攻击脆弱。
RC2 的分组长度为 64 位,密钥长度 1-128 位。它采用 16 轮不平衡 Feistel 结构的混淆操作和 2 轮扰乱操作。
# RC4 / ARC4 / ARCFOUR
RC4(Rivest Cipher 4)是 Ron Rivest 设计的一种流密码,曾经非常流行,被广泛用于 SSL 和 WPA 等协议,但目前已经过时。
RC4 采用 40-2048 位的密钥,以及 2064 位的状态位(1684 个有效状态位)对数据进行加密,拥有很快的加密速度。但是它的密钥流能够被与伪随机序列区分开来。在 2015 年,比利时的密码研究员宣布了 RC4 的破解,能够在 75 小时内取得 Cookie 的内容。目前现代的密码学协议通常已经弃用 RC4。
# SEED
SEED 是韩国 KISA 研发的一种 Feistel 密码。
SEED 的密文分组为 128 位,密钥长度固定为 128 位,迭代轮数 16 轮,目前仍然具有较高的安全性。
# SM4 / SMS4
SM4(商密 - 4)是中国国密算法系列中的对称加密算法,属于 Feistel 密码。
SM4 的分组长度为 128 位,密钥长度固定为 128 位,采用非对称 Feistel 结构 32 轮迭代,具有很强的安全性和较高的性能,广泛用于中国标准 WLAN WAPI 和 TLS。
# 基本加解密指令
# 简单的加密指令
一个最简单的加密文件的示例如下,该指令通过 AES-128-CTR
加密算法对 plaintext.txt
文件进行加密:
openssl enc -e -AES-128-CTR -in plaintext.txt -out ciphertext.txt |
OpenSSL 此时会提醒你输入密码:
enter AES-128-CTR encryption password: |
输入密钥后,OpenSSL 会提醒你输入确认密码:
Verifying - enter AES-128-CTR encryption password: |
如果确认密码与密码一致,那么文件将开始加密。但是,这种加密方式已经过时,OpenSSL 此时会弹出提示:
*** WARNING : deprecated key derivation used. | |
Using -iter or -pbkdf2 would be better. |
# 简单的解密指令
一个最简单的解密文件的示例如下,该指令尝试通过 AES-128-CTR
加密算法对 ciphertext.txt
文件进行解密:
openssl enc -d -AES-128-CTR -in ciphertext.txt -out decryptedtext.txt |
OpenSSL 此时会提醒你输入密码:
enter AES-128-CTR decryption password: |
密码如果正确,OpenSSL 将会解密文件。但它仍然会提醒你这种加密方式已经过时,会弹出提示:
*** WARNING : deprecated key derivation used. | |
Using -iter or -pbkdf2 would be better. |
# PBKDF2、迭代次数与盐
OpenSSL 目前并不鼓励直接使用字符串作为密钥,而是推荐使用 PBKDF2 生成加密密钥。
openssl enc
有这两个 KDF 参数:
-PBKDF2
:PBKDF2(Password-Based Key Derivation Function 2)是一种密钥推到函数,它能够从用户提供的密码中推导出实际的加密密钥,能够有效增强密码安全性,避免爆破原始密码。
-iter
:迭代次数(Iterations)指定了 PBKDF2 的迭代轮数,迭代轮数越高,密码的安全性相对就越高,但也会消耗更多的计算资源。一般建议设置在 80000 以上。(建议来源:Bitwarden)
-salt
:盐(Salt)是一个随机生成的唯一值,它在每一轮迭代中与输入值连接在一起参加 KDF 迭代,进一步增加了彩虹表攻击和爆破的难度。这个选项是默认开启的。
# 示例:使用 PBKDF2 与盐进行加解密
以下这条指令通过 AES-128-CTR
加密算法对 plaintext.txt
文件进行加密,使用加盐 PBKDF2,迭代次数 80000,输出文件为 ciphertext.txt。
openssl enc -e -AES-128-CTR -pbkdf2 -iter 80000 -salt -in plaintext.txt -out ciphertext.txt |
以下这条指令通过 AES-128-CTR
加密算法对 ciphert.txt
文件进行解密,使用加盐 PBKDF2,迭代次数 80000,输出文件为 decryptedtext.txt。
openssl enc -d -AES-128-CTR -pbkdf2 -iter 80000 -salt -in ciphertext.txt -out decryptedrtext.txt |
# 总体选择参数
# -help
陈列 OpenSSL enc
指令的帮助:
openssl enc -h |
或:
openssl enc -help |
它的输出如下:
Usage: enc [options] | |
General options: | |
-help Display this summary | |
-list List ciphers | |
-ciphers Alias for -list | |
-e Encrypt | |
-d Decrypt | |
-p Print the iv/key | |
-P Print the iv/key and exit | |
-engine val Use engine, possibly a hardware device | |
Input options: | |
-in infile Input file | |
-k val Passphrase | |
-kfile infile Read passphrase from file | |
Output options: | |
-out outfile Output file | |
-pass val Passphrase source | |
-v Verbose output | |
-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 | |
Encryption options: | |
-nopad Disable standard block padding | |
-salt Use salt in the KDF (default) | |
-nosalt Do not use salt in the KDF | |
-debug Print debug info | |
-bufsize val Buffer size | |
-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 the use of PBKDF2 | |
Default: 10000 | |
-pbkdf2 Use password-based key derivation function 2 (PBKDF2) | |
Use -iter to change the iteration count from 10000 | |
-none Don't encrypt | |
-* Any supported cipher | |
Random state options: | |
-rand val Load the given file(s) into the random number generator | |
-writerand outfile Write random data to the specified file | |
Provider options: | |
-provider-path val Provider load path (must be before 'provider' argument if required) | |
-provider val Provider to load (can be specified multiple times) | |
-propquery val Property query used when fetching algorithms |
# -list 或 -ciphers
列出 OpenSSL 支持的对称加密算法:
openssl enc -list |
或:
openssl enc -ciphers |
以 OpenSSL 3.1.2 版本为例,它的输出如下:
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 |
# -e
加密指令,例如:
openssl enc -AES-128-CTR -e -pbkdf2 -iter 80000 -salt -in plaintext.txt -out ciphertext.txt |
这条指令通过 AES-128-CTR
加密算法对 plaintext.txt
进行加密,输出到 ciphertext.txt
当中,密钥派生函数采用 PBKDF2
,迭代次数 80000
,加盐。
# -d
解密指令,例如:
openssl enc -AES-128-CTR -d -pbkdf2 -iter 80000 -salt ciphertext.txt -out decrypted.txt |
这条指令通过 AES-128-CTR
加密算法对 ciphertext.txt
进行解密,输出到 decrypted.txt
当中,密钥派生函数采用 PBKDF2
,迭代次数 80000
,加盐。
# -p 或 -P
输出 IV(Initialization Vector,初始化向量)和密钥,加盐也会输出盐值。
openssl enc -p -AES-128-CTR -e -pbkdf2 -iter 80000 -salt -in plaintext.txt -out ciphertext.txt |
它的输出为:
salt=EEADC4C2FABA433D | |
key=BD956B91B899D59A02DA992B65908A6F | |
iv =6AC35A79C1EE8C7192680E294696D279 |
# -engine
指定加密引擎,一般来说并不需要这么做,除非你有特殊需求。
# 输入参数
# -in
指定输入文档,例如 -in plaintext.txt
就是指以 plaintext.txt
文件作为输入。
# -k
指定加密密钥,例如:
openssl enc -e -AES-128-CTR -pbkdf2 -iter 80000 -salt -k your_awesome_password -in plaintext.txt -out ciphertext.txt |
其中 -k your_awesome_password
就指定了初始密钥为 "your_awesome_password"
# -kfile
从指定文件的第一行中导入密钥,例如:
openssl enc -e -AES-128-CTR -pbkdf2 -iter 80000 -salt -kfile your_awesome_password.bin -in plaintext.txt -out ciphertext.txt |
其中 -kfile your_awesome_password.bin
就指定了初始密钥从 your_awesome_password.bin
这个文件的第一行中导入。
# 输出参数
# -out
指定输出文档,例如 -out ciphertext.txt
就是指输出到 ciphertext.txt
这个文件中。如果没有这个文件,那么就新建。
# pass
指定密码的来源。
# 直接在命令行中提供密码
例如这条命令,直接指定密码为 your_awesome_password
:
openssl enc -AES-128-CTR -e -pass pass:your_awesome_password -in plaintext.txt -out ciphertext.txt |
# 从文件中读取密码
例如这条命令,从 password.txt
中的第一行读取密码:
openssl enc -AES-128-CTR -e -pass file:password.txt -in plaintext.txxt -out ciphertext.txt |
# 使用环境变量提供密码
例如这条命令,将尝试从系统的 OPENSSL_PASSWORD
环境变量读取密码:
openssl enc -AES-128-CTR -e -pass env:OPENSSL_PASSWORD -in plaintext.txt -out ciphertext.txt |
# -v
输出详细信息,例如:
openssl enc -v -e -AES-128-CTR -pbkdf2 -iter 80000 -salt -k your_awesome_password -in plaintext.txt -out ciphertext.txt |
这是它的输出:
bufsize=8192 | |
bytes read : 64 | |
bytes written: 80 |
# -a 或 -base64
Base64 编解码选项,如果是加密则将输出进行 Base64 编码,如果是解密则对输入先进行 Base64 解码。
例如:
openssl enc -base64 -e -AES-128-CTR -pbkdf2 -iter 80000 -salt -k your_awesome_password -in plaintext.txt -out ciphertext.txt |
这样你就会得到 Base64 编码的输出,而不是一堆乱码了:
U2FsdGVkX18mc9HLpslcxebFcULw/x3pPduiYwtum8dFM0AFH0h0o3Wri6K4LXVF | |
HFj/F0SeXy4Ma3odakvf2oRuM8C4CGPHICzSq2/X830= |
# -A
与 -a
或 -base64
一同使用,将 Base64 编码的缓冲区输出为单行文本。对于需要嵌入单行数据或者脚本的场景或许很有用。
例如:
openssl enc -A -base64 -e -AES-128-CTR -pbkdf2 -iter 80000 -salt -k your_awesome_password -in plaintext.txt -out ciphertext.txt |
得到的输出:
U2FsdGVkX19CVxeyE43LfGZf9QR73J7HXEYgc2PmfcElfbIwwvrUS1VRrCfKUqjkL9k2ldAVxTXdmf0c41rluoMKY+On4rKwzRpZlY2Vv84= |
# 加密选项
# -nopad
禁用分组加密算法的块填充。此时如果数据长度不是分组大小的整数倍,可能会出错。
# -salt
为 KDF 加盐,默认就是开启的。
例如:
openssl enc -e -AES-128-CTR -pbkdf2 -iter 80000 -salt -in plaintext.txt -out ciphertext.txt |
# -nosalt
手动指定 KDF 不使用盐,不推荐且不安全,这会削弱加密面对彩虹表攻击和爆破攻击的强度。
openssl enc -e -AES-128-CTR -pbkdf2 -iter 80000 -nosalt -in plaintext.txt -out ciphertext.txt |
# -debug
输出调试信息,例如:
openssl enc -e -debug -AES-128-CTR -pass pass:your_awesome_password -pbkdf2 -iter 80000 -salt -in plaintext.txt -out ciphertext.txt |
一个示例输出是:
in plaintext.txt -out ciphertext.txt | |
BIO[0x1e9bc5cf7f0]: write(0,8) - FILE pointer | |
BIO[0x1e9bc5cf7f0]: write return 1 processed: 8 | |
BIO[0x1e9bc5cf7f0]: write(0,8) - FILE pointer | |
BIO[0x1e9bc5cf7f0]: write return 1 processed: 8 | |
BIO[0x1e9bc5e02a0]: ctrl(6) - cipher | |
BIO[0x1e9bc5cf7f0]: ctrl(6) - FILE pointer | |
BIO[0x1e9bc5cf7f0]: ctrl return 0 | |
BIO[0x1e9bc5e02a0]: ctrl return 0 | |
BIO[0x1e9bc5d0600]: ctrl(10) - FILE pointer | |
BIO[0x1e9bc5d0600]: ctrl return 0 | |
BIO[0x1e9bc5d0600]: ctrl(2) - FILE pointer | |
BIO[0x1e9bc5d0600]: ctrl return 0 | |
BIO[0x1e9bc5d0600]: read(0,8192) - FILE pointer | |
BIO[0x1e9bc5d0600]: read return 1 processed: 64 | |
BIO[0x1e9bc5e02a0]: write(0,64) - cipher | |
BIO[0x1e9bc5cf7f0]: write(0,64) - FILE pointer | |
BIO[0x1e9bc5cf7f0]: write return 1 processed: 64 | |
BIO[0x1e9bc5e02a0]: write return 1 processed: 64 | |
BIO[0x1e9bc5d0600]: ctrl(10) - FILE pointer | |
BIO[0x1e9bc5d0600]: ctrl return 0 | |
BIO[0x1e9bc5d0600]: ctrl(2) - FILE pointer | |
BIO[0x1e9bc5d0600]: ctrl return 1 | |
BIO[0x1e9bc5e02a0]: ctrl(11) - cipher | |
BIO[0x1e9bc5cf7f0]: ctrl(11) - FILE pointer | |
BIO[0x1e9bc5cf7f0]: ctrl return 1 | |
BIO[0x1e9bc5e02a0]: ctrl return 1 | |
BIO[0x1e9bc5d0600]: Free - FILE pointer | |
BIO[0x1e9bc5cf7f0]: Free - FILE pointer | |
BIO[0x1e9bc5e02a0]: Free - cipher |
这其实是 OpenSSL API 给出的一些日志信息,其中涉及到 C 语言的操作,希望了解底层实现或者需要功能调试的可能会用到这个选项。
# -bufsize
手动调整 OpenSSL 缓冲区的大小,这个值默认情况下是 8192B,个人认为大多数情况下没必要修改。
更大的缓冲区在处理大文件时能减少 IO 次数,提升性能,但会引起更大的内存开销;更小的缓冲区处理小文件时能节省内存,但是处理大文件时 IO 次数会提高,性能会受到影响。
一个示例,把缓冲区修改为 1024B:
openssl enc -e -AES-128-CTR -pass pass:your_awesome_password -pbkdf2 -iter 80000 -salt -bufsize 1024 -in plaintext.txt -out ciphertext.txt |
# -K
手动指定初始密钥(Raw Key),绕过 KDF。输入形式为 16 进制。必须与 -iv
一同使用。
(PS:个人观点,除非你十分清楚你在做什么,否则不建议这么做)
例如,将 Raw Key 手动覆盖为 dc76d65a6ccf7f33fd8ecb7fe640e272
,将 IV 手动覆盖为 12caf7e7136907d82c6a01a0e3b7fc16
:
openssl enc -e -AES-128-CTR -K dc76d65a6ccf7f33fd8ecb7fe640e272 -iv 12caf7e7136907d82c6a01a0e3b7fc16 -in plaintext.txt -out ciphertext.txt |
# -iv
手动指定初始化向量(Initialization Vector, IV),绕过自带的 IV 发生器。输入形式为 16 进制。
(PS:个人观点,除非你十分清楚你在做什么,否则不建议这么做)
例如,将 Raw Key 手动覆盖为 dc76d65a6ccf7f33fd8ecb7fe640e272
,将 IV 手动覆盖为 12caf7e7136907d82c6a01a0e3b7fc16
:
openssl enc -e -AES-128-CTR -K dc76d65a6ccf7f33fd8ecb7fe640e272 -iv 12caf7e7136907d82c6a01a0e3b7fc16 -in plaintext.txt -out ciphertext.txt |
# -S
手动指定 KDF 的盐值(Salt),绕过自带的 Salt 发生器。输入形式为 16 进制。
(PS:个人观点,除非你十分清楚你在做什么,否则不建议这么做)
例如,将盐值手动覆盖为 4351431709882387
:
openssl enc -e -AES-128-CTR -pass pass:your_awesome_password -pbkdf2 -iter 80000 -salt -S 4351431709882387 -in plaintext.txt -out ciphertext.txt |
# -md
手动指定 KDF 使用的散列算法,绕过默认的散列算法。一般而言,没必要。
(PS:个人观点,除非你十分清楚你在做什么,否则不建议这么做)
例如,将散列算法手动修改为 SM3
:
openssl enc -e -AES-128-CTR -pass pass:your_awesome_password -pbkdf2 -iter 80000 -salt -md SM3 -in plaintext.txt -out ciphertext.txt |
# -iter
手动指定 KDF 的迭代次数,覆盖默认的迭代次数(10000)。
例如,将 KDF 的迭代次数手动修改为 80000
:
openssl enc -e -AES-128-CTR -pass pass:your_awesome_password -pbkdf2 -iter 80000 -salt -in plaintext.txt -out ciphertext.txt |
# -pbkdf2
使用 PBKDF2 来生成初始密钥,这是一种良好的安全实践:
openssl enc -e -AES-128-CTR -pass pass:your_awesome_password -pbkdf2 -iter 80000 -salt -in plaintext.txt -out ciphertext.txt |
# -none
不进行加密,通常是调试时使用的。
# 随机状态选项
# -rand
将选定的文件加载到随机数生成器当中,提供额外的安全性。最好使用可靠的随机源,例如在 Linux 系统上:
openssl enc -e -AES-128-CTR -pass pass:your_awesome_password -pbkdf2 -iter 80000 -salt -in plaintext.txt -out ciphertext.txt -rand /dev/urandom |
# writerand
向选定的文件输出生成的随机数据。
openssl enc -e -AES-128-CTR -pass pass:your_awesome_password -pbkdf2 -iter 80000 -salt -in plaintext.txt -out ciphertext.txt -writerand random.txt |