我想使用一个密码加密和解密一个文件。
我如何使用 OpenSSL 来做到这一点?
加密:
openssl aes-256-cbc -a -salt -pbkdf2 -in secrets.txt -out secrets.txt.enc
解密:
openssl aes-256-cbc -d -a -pbkdf2 -in secrets.txt.enc -out secrets.txt.new
您可能希望使用gpg
而不是openssl
因此请参阅此答案末尾的“附加说明” 。但是要使用以下方法回答问题openssl
:
加密:
openssl enc -aes-256-cbc -in un_encrypted.data -out encrypted.data
解密:
openssl enc -d -aes-256-cbc -in encrypted.data -out un_encrypted.data
注意:加密或解密时会提示您输入密码。
您最好的信息来源openssl enc
可能是:https ://www.openssl.org/docs/man1.1.1/man1/enc.html
命令行:
openssl enc
采用以下形式:
openssl enc -ciphername [-in filename] [-out filename] [-pass arg]
[-e] [-d] [-a/-base64] [-A] [-k password] [-kfile filename]
[-K key] [-iv IV] [-S salt] [-salt] [-nosalt] [-z] [-md] [-p] [-P]
[-bufsize number] [-nopad] [-debug] [-none] [-engine id]
关于您的问题的最有用参数的解释:
-e
Encrypt the input data: this is the default.
-d
Decrypt the input data.
-k <password>
Only use this if you want to pass the password as an argument.
Usually you can leave this out and you will be prompted for a
password. The password is used to derive the actual key which
is used to encrypt your data. Using this parameter is typically
not considered secure because your password appears in
plain-text on the command line and will likely be recorded in
bash history.
-kfile <filename>
Read the password from the first line of <filename> instead of
from the command line as above.
-a
base64 process the data. This means that if encryption is taking
place the data is base64 encoded after encryption. If decryption
is set then the input data is base64 decoded before being
decrypted.
You likely DON'T need to use this. This will likely increase the
file size for non-text data. Only use this if you need to send
data in the form of text format via email etc.
-salt
To use a salt (randomly generated) when encrypting. You always
want to use a salt while encrypting. This parameter is actually
redundant because a salt is used whether you use this or not
which is why it was not used in the "Short Answer" above!
-K key
The actual key to use: this must be represented as a string
comprised only of hex digits. If only the key is specified, the
IV must additionally be specified using the -iv option. When
both a key and a password are specified, the key given with the
-K option will be used and the IV generated from the password
will be taken. It probably does not make much sense to specify
both key and password.
-iv IV
The actual IV to use: this must be represented as a string
comprised only of hex digits. When only the key is specified
using the -K option, the IV must explicitly be defined. When a
password is being specified using one of the other options, the
IV is generated from this password.
-md digest
Use the specified digest to create the key from the passphrase.
The default algorithm as of this writing is sha-256. But this
has changed over time. It was md5 in the past. So you might want
to specify this parameter every time to alleviate problems when
moving your encrypted data from one system to another or when
updating openssl to a newer version.
尽管您已经特别询问了 OpenSSL,但您可能希望考虑使用 GPG 来代替基于本文OpenSSL vs GPG 加密异地备份的加密目的?
要使用 GPG 执行相同操作,您可以使用以下命令:
加密:
gpg --output encrypted.data --symmetric --cipher-algo AES256 un_encrypted.data
解密:
gpg --output un_encrypted.data --decrypt encrypted.data
注意:加密或解密时会提示您输入密码。
加密:
openssl enc -in infile.txt -out encrypted.dat -e -aes256 -k symmetrickey
解密:
openssl enc -in encrypted.dat -out outfile.txt -d -aes256 -k symmetrickey
有关详细信息,请参阅openssl(1)
文档。
不要使用 OPENSSL 默认密钥派生。
目前接受的答案使用它,不再推荐和安全。
攻击者简单地暴力破解密钥是非常可行的。
https://www.ietf.org/rfc/rfc2898.txt
PBKDF1 应用一个散列函数,它应该是 MD2 [6]、MD5 [19] 或 SHA-1 [18],以派生密钥。派生密钥的长度受哈希函数输出长度的限制,MD2 和 MD5 为 16 个八位字节,SHA-1 为 20 个八位字节。PBKDF1 与 PKCS #5 v1.5 中的密钥派生过程兼容。仅推荐 PBKDF1 与现有应用程序兼容,因为它生成的密钥对于某些应用程序可能不够大。
PBKDF2 应用伪随机函数(参见附录 B.1 中的示例)来派生密钥。派生密钥的长度基本上是无界的。(但是,派生密钥的最大有效搜索空间可能受到底层伪随机函数结构的限制。有关进一步讨论,请参见附录 B.1。)建议将 PBKDF2 用于新应用程序。
做这个:
openssl enc -aes-256-cbc -pbkdf2 -iter 20000 -in hello -out hello.enc -k meow
openssl enc -d -aes-256-cbc -pbkdf2 -iter 20000 -in hello.enc -out hello.out
注意:解密中的迭代必须与加密中的迭代相同。
迭代次数必须至少为 10000。这是关于迭代次数的一个很好的答案:https ://security.stackexchange.com/a/3993
还有……我们这里有足够多的人推荐 GPG。阅读该死的问题。
如其他答案中所述,以前版本的 openssl 使用弱密钥派生函数从密码中派生 AES 加密密钥。但是,openssl v1.1.1 支持更强大的密钥派生功能,其中密钥是使用pbkdf2
随机生成的盐和多次迭代 sha256 散列(默认为 10,000)从密码中派生的。
要加密文件:
openssl aes-256-cbc -e -salt -pbkdf2 -iter 10000 -in plaintextfilename -out encryptedfilename
要解密文件:
openssl aes-256-cbc -d -salt -pbkdf2 -iter 10000 -in encryptedfilename -out plaintextfilename
使用随机生成的公钥进行更新。
加密:
openssl enc -aes-256-cbc -a -salt -in {raw data} -out {encrypted data} -pass file:{random key}
解密:
openssl enc -d -aes-256-cbc -in {ciphered data} -out {raw data}
加密:
$ openssl bf < arquivo.txt > arquivo.txt.bf
解密:
$ openssl bf -d < arquivo.txt.bf > arquivo.txt
bf === CBC 模式下的河豚
请注意,OpenSSL CLI 使用弱非标准算法将密码转换为密钥,并且安装 GPG 会导致将各种文件添加到您的主目录并运行 gpg-agent 后台进程。如果您希望使用现有工具实现最大的可移植性和控制,您可以使用 PHP 或 Python 访问较低级别的 API,并直接传入完整的 AES 密钥和 IV。
通过 Bash 调用 PHP 示例:
IV='c2FtcGxlLWFlcy1pdjEyMw=='
KEY='Twsn8eh2w2HbVCF5zKArlY+Mv5ZwVyaGlk5QkeoSlmc='
INPUT=123456789023456
ENCRYPTED=$(php -r "print(openssl_encrypt('$INPUT','aes-256-ctr',base64_decode('$KEY'),OPENSSL_ZERO_PADDING,base64_decode('$IV')));")
echo '$ENCRYPTED='$ENCRYPTED
DECRYPTED=$(php -r "print(openssl_decrypt('$ENCRYPTED','aes-256-ctr',base64_decode('$KEY'),OPENSSL_ZERO_PADDING,base64_decode('$IV')));")
echo '$DECRYPTED='$DECRYPTED
这输出:
$ENCRYPTED=nzRi252dayEsGXZOTPXW
$DECRYPTED=123456789023456
您还可以使用 PHP 的openssl_pbkdf2
函数将密码短语安全地转换为密钥。
我在网上找到了一个开源程序,它使用 openssl 来加密和解密文件。它使用单个密码执行此操作。这个开源脚本的伟大之处在于它通过粉碎文件来删除原始的未加密文件。但危险的是,一旦原始未加密文件消失,您必须确保记住您的密码,否则他们将无法解密您的文件。
这是github上的链接
https://github.com/EgbieAnderson1/linux_file_encryptor/blob/master/file_encrypt.py