如何快速使用AES加密文件?

我想使用AES-256加密一个文件。如何快速简便地完成这个操作,以及如何解密它 - 或者让其他人解密它?
7个回答

很遗憾,保护你的东西没有简单的解决方案。考虑一下你的使用情况,也许除了普通的AES加密,还有更适合的选择。
- 使用像密码管理器Keyring这样的工具。 - 加密你的主目录(在Ubuntu安装程序中非常容易实现)。 - 如果你想要通过电子邮件进行安全通信,可以使用GPG。 - 如果你想要进行安全即时通讯,可以使用Pidgin上的OTR。 - 用Cryptocat进行安全聊天。
如果您想要一个非常简单的平台无关加密方法,您可以使用openssl。
请注意:您可以使用此方法来隐藏生日礼物想法.txt文件以避免被舍友发现,但不要指望它对抗有决心的攻击者是安全的!
如评论中所指出的那样,此方法使用了一个天真的密钥派生函数,因此您的密码需要非常强大才能有机会保持安全。
此外,此方法不对密文进行身份验证,这意味着攻击者可以修改或损坏内容而您察觉不到。
对于许多类型的安全性来说,仅仅使用加密是不够的(例如,您不能仅仅使用加密来进行安全通信)。
如果您还是想要使用openssl:
加密: openssl aes-256-cbc -in attack-plan.txt -out message.enc
解密: openssl aes-256-cbc -d -in message.enc -out plain-text.txt
你可以使用openssl来对消息进行base64编码,只需在加密和解密时都使用-a开关。这样,你就可以将密文粘贴到电子邮件中,例如。它会看起来像这样:
stefano:~$ openssl aes-256-cbc -in attack-plan.txt -a
enter aes-256-cbc encryption password:
Verifying - enter aes-256-cbc encryption password:
U2FsdGVkX192dXI7yHGs/4Ed+xEC3ejXFINKO6Hufnc=

请注意,您可以选择不同的密码和操作模式。对于正常使用,我建议使用CBC模式下的AES 256位加密算法。以下是您可用的密码和操作模式(仅计算AES):
aes-128-cbc ← this is okay
aes-128-ecb
aes-192-cbc
aes-192-ecb
aes-256-cbc ← this is recommended
aes-256-ecb

另请参阅:

请注意:

OpenSSL会要求您输入密码。这不是加密密钥,不限制为32个字节!如果您打算与他人传输文件,您共享的密码应该非常强大。您可以使用此网站来了解您的密码有多好:

警告:我已经检查过这些网站不会将您的密码发送到服务器,但这可能随时发生变化。在输入强密码之前,请使用开发工具/检查器检查它们是否发送任何内容。


10openssl aes-256-cbcopenssl enc -aes-256-cbc更简洁且同样有效。通过运行man enc可以查看此命令的手册页面。对于不应被篡改的数据,永远不要使用ecb模式,而是使用cbc模式。由于默认设置已经包含了盐值(salt),因此-salt是多余的。如果省略-out filename参数,则输出将被写入标准输出,这在只需要分析数据而不需要将其写入磁盘时非常有用。下一个命令用于统计明文的行数:openssl aes-256-cbc -d -in filename | wc -l。(另一个用途,读取文件:openssl aes-256-cbc -d -in filename | less - Lekensteyn
谢谢 @Lekensteyn!我在回答中加入了一些你的建议。 - Stefano Palazzo
1我在脚本中几乎完全使用这个命令:/usr/bin/openssl enc -aes-256-cbc -a -salt -in $1 -out ${1}.enc,反向操作与您预期的相同。 - belacqua
1没有理由偏爱AES 256而不是AES 128。@Lekensteyn也不要使用ECB来处理机密数据-基本上ECB不应该被使用(对于专家而言:除非在某些非常特殊的情况下,否则不应该使用ECB)。更一般地说,“openssl”命令行工具主要是用于测试OpenSSL库的概念验证。这个问题的正确答案是GPG或者像7z这样的压缩软件。 - Gilles 'SO- stop being evil'
1我想补充一点,如果你的密码强度较弱,openssl enc 实际上并不是很安全。我之前推荐过某些使用 openssl enc 的方法,但现在建议改用 gpg,因为它更好地使用了 KDF。请参考这个答案 - Lekensteyn
2不建议使用低级别的OpenSSL。它不提供任何HMAC功能,并且正如@Lekensteyn所指出的那样,它缺乏适当的KDF。 - gertvdijk
等一下 - 人们居然会在第三方网站上输入他们的“强密码”。哇。这就是SSH机器人播种字典攻击的方式。 - Andrew
1@Amoss 你是对的。我已经添加了一个警告。当然,我们应该始终先检查,不相信任何人。在写这些话的时候(包括现在),这些网站并没有将你的密码发送到任何地方。 - Stefano Palazzo
crypto.cat似乎已经变成了一个糟糕的无关网站。也许应该删除或替换这个链接。 - Akito

我喜欢使用 gpg 命令:
加密:
gpg --cipher-algo AES256 --symmetric filename.tar.gz

速记:

gpg --cipher-algo AES256 -c filename.tar.gz

这将要求输入密码。

解密:

gpg --output filename.tar.gz --decrypt filename.tar.gz.gpg

速记:
gpg -o filename.tar.gz -d filename.tar.gz.gpg

你还可以在~/.gnupg/gpg.conf中添加cipher-algo AES256,使AES256成为默认选项。(根据manpage,它是CAST5

您还可以使用AES(即AES-128)。 AES-128稍微快一些,并且不会降低安全性。 - Gilles 'SO- stop being evil'
2+1。同时注意,GnuPG在使用AES时还为您提供了消息认证(HMAC),而OpenSSL则缺乏此功能(这是撰写本回答时最受赞同的答案)。背景信息:http://superuser.com/a/633716/157409 - gertvdijk
1看起来第一个命令在20.04版本中将您的密码存储在某个地方,因此当您解密文件时,它甚至不会要求您输入密码。这是出乎意料的。而且我甚至无法通过--no-keyring选项停止gpg这样做。 - MWB
@MWB 这也让我感到惊讶。你可以通过使用--no-symkey-cache标志来防止这种情况发生,或者将no-symkey-cache一行添加到你的~/.gnupg/gpg.conf文件中。如果在更新配置文件之前密码已经被缓存,你可以通过重新加载代理来清除它:echo RELOADAGENT | gpg-connect-agent - wilkystyle
原来,如果你在大规模运行这个程序(比如解密数百万个文件),可能会遇到一些安全内存限制,导致部分文件无法解密。 - Alper

7z(当使用密码选项时)使用256位AES加密(带有SHA256密钥拉伸)。
安装它(p7zip-full),右键单击要加密的文件或目录,然后选择压缩、.7z和其他选项/密码。

enter image description here

解密的话,右键点击.7z文件,然后选择在此处提取

1如何启动7z的图形用户界面(GUI)? - m0skit0

aescrypt

这个链接的网站包含一个开源的256位AES加密/解密工具,支持多平台 - MacOs、Windows、Linux和其他通过Java。

加密: aescrypt -e <file>

解密: aescrypt -d <file>

您可以使用以下语法备份和加密您的主文件夹:

tar -cvf - /home/<home_folder> | aescrypt -e -p <password_message> - > backup.tar.aes

Ubuntu安装

下载并解压源代码

make
sudo make install

其他平台

从网站上下载二进制文件或源代码。


很多我本来会提出的建议已经在这个帖子中提出了。基本上,openssl是加密文件或脚本最简单的方法。然而,我要警告不要使用AES-256,因为它并不适用于某些平台上的所有openssl版本。大多数较新的操作系统,比如Linux,都有它。但其他一些平台,比如AIX 5.3(我认为HP-UX也是如此),没有它。如果你打算在不同平台上使用你的文件或脚本,我强烈建议使用AES-128,因为它在任何地方都可用。 如何“快速简便地”使用AES-128加密文件? 一个类似于www.ShellScrypt.com的网站,非常频繁地使用openssl AES-128来加密shell脚本,并生成可执行的加密副本。您只需将脚本粘贴到该网站上,就会为您生成一个zip文件。该zip文件将包含您的文件的加密版本(如果是脚本,则还可以执行)。这使您能够“轻松”和“方便地”加密文件/脚本,而无需满足每个系统上使用脚本或运行多个复杂且令人困惑的openssl命令的要求。
下面是一个基本的“加密/解密”openssl命令示例,使用AES-128:
test@test-VirtualBox:~$ 
test@test-VirtualBox:~$ echo precious-content | openssl aes-128-cbc -a -salt -k mypassword
U2FsdGVkX1+K6tvItr9eEI4yC4nZPK8b6o4fc0DR/Vzh7HqpE96se8Fu/BhM314z
test@test-VirtualBox:~$
test@test-VirtualBox:~$ echo U2FsdGVkX1+K6tvItr9eEI4yC4nZPK8b6o4fc0DR/Vzh7HqpE96se8Fu/BhM314z | openssl aes-128-cbc -a -d -salt -k mypassword
precious-content
test@test-VirtualBox:~$ 
test@test-VirtualBox:~$

2只是留个评论告诉大家,“shellscrypt.com”已经崩溃了(也就是说,网站消失了)。 - e-sushi

提到自OpenSSL 1.1.0以来添加的最新选项openssl。在stefano-palazzo的回答基础上进行扩展:
openssl enc -aes-256-cbc -a -e -in input.tar.gz -out oupput.enc -pbkdf2 -iter 1000000 -md sha512

它使用了一个密钥派生函数,如果没有它,暴力破解密码将变得更容易。
用于解密的方法如下:
openssl enc -aes-256-cbc -a -d -in output.tar.xz.enc -out output.tar.xz -pbkdf2 -iter 1000000 -md sha512

解释参数:
enc 代表加密
-aes-256-cbc 是使用 AES 密码的 一个好方法
-a 在加密之后或解密之前对数据进行 base64 编码
-d 解密
-e 加密
-in 输入文件
-out 输出文件
-pbkdf2 将密钥扩展为难以破解的 密钥派生函数
-iter 扩展密钥的迭代次数,更多次意味着更高的安全性,适当的次数可以在 这里找到
-md sha512 用 SHA512 替换 PBKDF2 的哈希函数,比默认的 SHA256 更安全
-salt 在命令中没有提及,因为它是默认设置的,并且是增加安全性的非常好的方法,为什么如此请参考 这里的说明

除了Stefano Palazzo的回答之外,我创建了一个类似于base64命令的小bash函数。
它将对文件进行aes256加密,然后进行base64编码。在进行反向操作时,它将进行base64解码、解密,然后输出原始明文。
aes256() {
  decodeMe=""
  isPipe="$([ ! -t 0 ] && echo "true" || echo "false")"

  if [ "$1" = '-d' ] || [ "$1" = '--decode' ]; then
    decodeMe="-d"
    shift
  fi

  if [ "$isPipe" = "true" ]; then
    read input
    printf '%s\n' "$input" | openssl aes-256-cbc -a $decodeMe
    exitCode="$?"
  else
    openssl aes-256-cbc -a $decodeMe -in "$*"
    exitCode="$?"
  fi

  unset isPipe decodeMe input
  return "$exitCode"
}

使用方法:

echo "my string" | aes256
# enter aes-256-cbc encryption password
# Returns: U2FsdGVkX1++e/BhBGlNOzNvarqq7zI13S/hbiKVzXQ=

echo "U2FsdGVkX1++e/BhBGlNOzNvarqq7zI13S/hbiKVzXQ=" | aes256 -d
# enter aes-256-cbc decryption password
# Returns: my string

aes256 file.plain > file.crypt
# enter aes-256-cbc encryption password

aes256 -d file.crypt
# enter aes-256-cbc decryption password
# Spits out original unencrypted file.