如何使用OpenSSL加密/解密文件?

我想用一个密码加密和解密一个文件。

我如何使用OpenSSL来做到这一点?

677323 次浏览

安全警告: AES-256-CBC不提供经过身份验证的加密,容易受到填充oracle攻击攻击。你应该使用类似年龄的东西代替。

加密:

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

更多关于各种标志的详细信息

加密:

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)文档。

使用随机生成的公钥进行更新。

Encypt:

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来加密和解密文件。它只用一个密码就能做到这一点。这个开源脚本的伟大之处在于,它通过分解文件来删除原始的未加密文件。但危险的是,一旦原始的未加密文件消失了,你必须确保你记住了你的密码,否则他们就没有其他方法来解密你的文件。

这是github上的链接

https://github.com/EgbieAnderson1/linux_file_encryptor/blob/master/file_encrypt.py

更好的选择:GPG

虽然您已经特别询问了OpenSSL,但基于本文加密场外备份的OpenSSL vs GPG ?,您可能会考虑使用GPG来代替加密

要使用GPG来做同样的事情,您可以使用以下命令:

加密:

gpg --output encrypted.data --symmetric --cipher-algo AES256 un_encrypted.data

解密:

gpg --output un_encrypted.data --decrypt encrypted.data

注意:加密或解密时会提示输入密码。并使用--no-symkey-cache标志表示没有缓存。


回复:OpenSSL -简短回答

您可能想使用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 -长答案

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 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 Key和IV。

示例PHP调用通过Bash:

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默认密钥派生。

目前公认的答案使用它,它不再被推荐和安全。

对于攻击者来说,简单地暴力破解密钥是非常可行的。

https://www.ietf.org/rfc/rfc2898.txt

PBKDF1应用哈希函数,该哈希函数为MD2 [6], MD5[19]或 SHA-1[18],来推导密钥。派生键的长度是有界的 由哈希函数输出的长度决定,MD2为16字节 MD5和SHA-1的20字节。PBKDF1与该键兼容 在PKCS #5 v1.5中的推导过程。PBKDF1仅建议与现有的兼容 应用程序,因为它产生的键可能不够大 一些应用程序。< / p > 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和随机生成的salt,以及多次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

注意:在javascript中(使用web crypto api)可以在https://github.com/meixler/web-browser-based-file-encryption-decryption中找到等效/兼容的实现。