我想用一个密码加密和解密一个文件。
我如何使用OpenSSL来做到这一点?
我想用一个密码加密和解密一个文件。
我如何使用OpenSSL来做到这一点?
当前回答
安全警告: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
关于各种标志的更多细节
其他回答
安全警告: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 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函数安全地将密码短语转换为密钥。
更好的选择:GPG
虽然您特别询问了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
注意:加密或解密时会提示输入密码。使用——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 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的以前版本使用弱密钥派生函数从密码派生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上找到等效/兼容的实现。