使用 openssl 命令行加密字符串

Posted

技术标签:

【中文标题】使用 openssl 命令行加密字符串【英文标题】:Encrypt a string using openssl command line 【发布时间】:2012-04-23 19:22:20 【问题描述】:

我有一个 16 字节的字符,我想使用 openssl 将它加密成一个 16 字节的加密字符串。

然后需要将此加密字符串(以人类可读格式)提供给将要使用它的用户,并且该字符串将被解密为其原始 16 字节形式以进行比较和验证。谁能告诉我如何使用 openssl 命令行实现这一点。

提前致谢。

【问题讨论】:

从 16 字节加密为 16 字节不太可能产生人类可读的字符串。 +1 重新打开。这里要问什么是 100% 明显的。不过我会重申一下:如何使用openssl 命令加密字符串?这不是一项显而易见的任务,用户提供了他的请求的上下文。 @G-Wiz: “你如何使用 openssl 命令加密字符串” - 这是 Stack Overflow 的主题吗?它确实 not 似乎与编程相关。这听起来像是一个命令帮助请求,这更适合Super User。 @jww,我不同意这一点。但是问题应该被迁移,而不是关闭。 【参考方案1】:

试试这个

$ echo "a_byte_character" | openssl enc -base64

你有 100 多种密码类型

-aes-128-cbc               -aes-128-cfb               -aes-128-cfb1             
-aes-128-cfb8              -aes-128-ctr               -aes-128-ecb              
-aes-128-gcm               -aes-128-ofb               -aes-128-xts              
-aes-192-cbc               -aes-192-cfb               -aes-192-cfb1             
-aes-192-cfb8              -aes-192-ctr               -aes-192-ecb              
-aes-192-gcm               -aes-192-ofb               -aes-256-cbc              
-aes-256-cfb               -aes-256-cfb1              -aes-256-cfb8             
-aes-256-ctr               -aes-256-ecb               -aes-256-gcm              
-aes-256-ofb               -aes-256-xts               -aes128                   
-aes192                    -aes256                    -bf                       
-bf-cbc                    -bf-cfb                    -bf-ecb                   
-bf-ofb                    -blowfish                  -camellia-128-cbc         
-camellia-128-cfb          -camellia-128-cfb1         -camellia-128-cfb8        
-camellia-128-ecb          -camellia-128-ofb          -camellia-192-cbc         
-camellia-192-cfb          -camellia-192-cfb1         -camellia-192-cfb8        
-camellia-192-ecb          -camellia-192-ofb          -camellia-256-cbc         
-camellia-256-cfb          -camellia-256-cfb1         -camellia-256-cfb8        
-camellia-256-ecb          -camellia-256-ofb          -camellia128              
-camellia192               -camellia256               -cast                     
-cast-cbc                  -cast5-cbc                 -cast5-cfb                
-cast5-ecb                 -cast5-ofb                 -des                      
-des-cbc                   -des-cfb                   -des-cfb1                 
-des-cfb8                  -des-ecb                   -des-ede                  
-des-ede-cbc               -des-ede-cfb               -des-ede-ofb              
-des-ede3                  -des-ede3-cbc              -des-ede3-cfb             
-des-ede3-cfb1             -des-ede3-cfb8             -des-ede3-ofb             
-des-ofb                   -des3                      -desx                     
-desx-cbc                  -id-aes128-GCM             -id-aes192-GCM            
-id-aes256-GCM             -rc2                       -rc2-40-cbc               
-rc2-64-cbc                -rc2-cbc                   -rc2-cfb                  
-rc2-ecb                   -rc2-ofb                   -rc4                      
-rc4-40                    -rc4-hmac-md5              -seed                     
-seed-cbc                  -seed-cfb                  -seed-ecb                 
-seed-ofb

【讨论】:

请注意,“enc 实用程序不支持 XTS 模式下的密码。” 正如 Meyer 先生所说,令人遗憾的是,命令行不支持在同一运行中进行加密和身份验证的最佳密码,如 -aes-256-gcm .【参考方案2】:

试试这个:

echo 'foo' | openssl aes-256-cbc -a -salt
echo 'U2FsdGVkX1/QGdl4syQE8bLFSr2HzoAlcG299U/T/Xk=' | openssl aes-256-cbc -a -d -salt

运行

openssl list-cipher-commands 

列出所有可用的密码。

【讨论】:

【参考方案3】:

我有一个 16 字节的字符,我想使用 openssl 将它加密成一个 16 字节的加密字符串 [以人类可读的格式]

我相信您正在寻找 Format Preserving Encryption。我认为需要注意的是你必须从一个 16 字节的人类可读字符串开始。 Phillip Rogaway 有一篇关于技术的论文:Synopsis of Format-Preserving Encryption。论文内容很多,在 Stack Overflow 上一个段落都写不下。

如果您可以从较短的字符串开始并使用 OCB、OFB 或 CTR 等流模式,那么您可以对最终字符串进行 Base64 编码,以便结果为 16 字节且人类可读。 Base64 以 3 → 4 的速率扩展(3 个未编码扩展为 4 个编码),因此您需要长度为 12 个字符的较短字符串来实现 16 个人类可读字符。

据我所知,没有任何命令行工具可以本地执行此操作。您可以在命令行上使用 OpenSSL 与 AES/CTR 并通过base64 命令对其进行管道传输。以下内容很接近,但它以 11 个字符(而不是 12 个)开头:

$ echo 12345678901 | openssl enc -e -base64 -aes-128-ctr -nopad -nosalt -k secret_password
cSTzU8+UPQQwpRAq

另外,您真的需要了解-k 选项(以及-K),以及它如何派生密钥以便您可以在 OpenSSL 命令之外执行此操作(如果需要)。

【讨论】:

这个确切的命令有效,但显示了一个警告:*** WARNING : deprecated key derivation used. Using -iter or -pbkdf2 would be better. 所以我添加了-pbkdf2 参数并运行$ echo 12345678901 | openssl enc -e -base64 -aes-128-ctr -pbkdf2 -nopad -nosalt -k secret_password iN/tCC7mTw3AWPn2 以避免这个警告 -nopad 不影响输出,因此:echo 12345678901 | openssl enc -e -base64 -aes-128-ctr -nosalt -pbkdf2 -k secret_password 产生与 echo 12345678901 | openssl enc -e -base64 -aes-128-ctr -nopad -nosalt -pbkdf2 -k secret_password 相同的输出 然后解密? 回显加密字符串并在管道 openssl 命令中将 -e 标志更改为 -d【参考方案4】:

这是在命令行上使用 openssl 加密字符串的一种方法(必须输入两次密码):

echo -n "aaaabbbbccccdddd" | openssl enc -e -aes-256-cbc -a -salt
enter aes-256-cbc encryption password:
Verifying - enter aes-256-cbc encryption password:

这是输出的样子:

U2FsdGVkX1/6LATntslD80T2HEIn3A0BqxarNfwbg31D2kI00dYbmBo8Mqt42PIm

编辑:据我所知,您无法控制输出的字节数。您可以对其进行 b64 或十六进制编码,仅此而已。此外,如果您想将该字符串保存到文件而不是标准输出,请使用 -out 选项。

【讨论】:

谢谢,但是有没有其他方法可以加密一个 16 个字符的字符串并在 Linux 中使用命令行生成一个 16 个字符的加密字符串 为什么输出必须正好是 16 个字节?为什么这很重要? 你为什么用-aes-256-cbc而不是-aes-256?有什么区别? "... 字符串将被解密为其原始的 16 字节形式以进行比较和验证" - 您有任何密钥管理要求吗?用户如何获得密钥? 这会给出警告“使用 -iter 或 -pbkdf2 会更好。”。我应该改用什么命令?

以上是关于使用 openssl 命令行加密字符串的主要内容,如果未能解决你的问题,请参考以下文章

OpenSSL 字符串解密问题

openssl 基本加密

OpenSSL命令行工具

openssl命令

不同openssl版本的行为差异

Openssl