我想使用一个密码来加密和解密一个文件。
如何使用OpenSSL做到这一点?
我想使用一个密码来加密和解密一个文件。
如何使用OpenSSL做到这一点?
Answers:
安全警告:AES-256-CBC不提供经过身份验证的加密,并且容易遭受填充oracle攻击。您应该改用age等。
加密:
openssl aes-256-cbc -a -salt -in secrets.txt -out secrets.txt.enc
解密:
openssl aes-256-cbc -d -a -in secrets.txt.enc -out secrets.txt.new
-md sha256
如果您打算在另一台计算机上使用此文件,则可以在@Kebman的注释中添加您的编码和解码命令。这样
您可能想使用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和GPG来加密异地备份?
要使用GPG进行相同的操作,请使用以下命令:
加密:
gpg --output encrypted.data --symmetric --cipher-algo AES256 un_encrypted.data
解密:
gpg --output un_encrypted.data --decrypt encrypted.data
注意:加密或解密时,系统会提示您输入密码。
gpg
让我解密文件而没有提示您输入密码。好像密码已存储了一段时间,我不想这样。
--no-symkey-cache
将gpg与一起使用,该选项似乎也禁用了缓存--symmetric
。
加密:
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)
文档。
-k symmetrickey
为-pass stdin
或-pass 'pass:PASSWORD'
-k symmetrickey
具有误导性。该-k
选项用于指定密码,OpenSSL从该密码派生对称密钥。如果要指定对称密钥,则必须使用该-K
选项。
请勿使用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 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}
我在http://bigthinkingapplied.com/key-based-encryption-using-openssl/上有完整的教程
请注意,OpenSSL CLI使用弱非标准算法将密码短语转换为密钥,并且将GPG安装结果添加到添加到主目录中的各种文件中,并运行gpg-agent后台进程。如果要最大程度地实现可移植性并使用现有工具进行控制,则可以使用PHP或Python访问较低级别的API,并直接传递完整的AES Key和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
如其他答案中所述,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
对mti2935的附加注释很好的答案。
似乎迭代次数越多越能防止暴力破解,并且您应该使用较高的迭代次数,因为这样才能在性能/资源上提供合理的价格。
在我的旧版Intel i3-7100上,加密了一个相当大的文件1.5GB:
time openssl enc -aes256 -e -pbkdf2 -iter 10000 -pass pass:"mypassword" -in "InputFile" -out "OutputFile"
Seconds: 2,564s
time openssl enc -aes256 -e -pbkdf2 -iter 262144 -pass pass:"mypassword" -in "InputFile" -out "OutputFile"
Seconds: 2,775s
没什么区别,虽然没有检查内存使用情况(?)
在当今的GPU以及明天更快的情况下,我想每秒钟可能进行数十亿次蛮力迭代。
12年前,a NVIDIA GeForce 8800 Ultra
可以迭代超过200.000百万/秒的迭代(不过是MD5哈希)
PKCS5_PBKDF2_HMAC
。您应该使用EVP_*
函数进行加密和解密。请参阅OpenSSL Wiki上的EVP对称加密和解密。实际上,您可能应该使用经过身份验证的加密,因为它既提供了机密性又提供了真实性。请参阅OpenSSL Wiki上的EVP身份验证加密和解密。