通过stdin安全地将密码传递给openssl

时间:2011-06-12 09:59:47

标签: security unix ssl openssl

我们知道我们可以使用以下命令使用openssl加密文件:

openssl aes-256-cbc -a -salt -in twitterpost.txt -out foo.enc -pass stdin

将从stdin读取密码。因此,要提前提供密码,我们所需要的只是前置

echo "someGoodPassword" |

到上面的命令。我的问题是:我怎样才能更安全地做到这一点?上述方法看起来不够安全。

我对此有一些评论,所以我可以更好地理解这个问题。

5 个答案:

答案 0 :(得分:17)

你使用的任何机制几乎都是root用户可以窥探的,所以请记住这一点。

echo选项将显示在“ps”列表中,使其易受普通用户窥探和查找密码的攻击。<​​/ p>

您可以使用-pass file:filename来使用文件,因此您可以使用:

sumask=$(umask)
umask 077
rm -f passfile
cat >passfile <<EOM
someGoodPassword
EOM
umask $sumask

这会创建该文件,其他帐户无法读取(但仍可由root读取)。假设脚本仅用于创建传递文件一次,就像重复该过程一样,它往往位于文件中,因此您需要chmod go-rwx该文件使其他用户无法读取。

然后你使用:

openssl aes-256-cbc -a -salt -in twitterpost.txt -out foo.enc -pass file:passfile

使用预先创建的密码文件执行加密。

其他机制-pass env:ENVVAR用于使用环境变量(再次将其放在那里而不会泄露它是诀窍)

答案 1 :(得分:15)

简短版

使用命名管道。

openssl aes-256-cbc -a -salt -in twitterpost.txt -out foo.enc -pass file:<( echo -n "someGoodPassword" )

长版

使用命名管道。您可以使用

在bash中创建它
<( *output* )

e.g。

<( echo -n "content" ) # without -n echo will add a newline

它将打开一个命名管道,通常是一个FIFO队列,您将在进程列表中看到类似

的内容
/dev/fd/63

它只能由当前用户读取,并在读取后自动关闭,因此您不必担心权限并清理磁盘(如果程序崩溃,管道将关闭,而您在另一个答案中建议的文件将保留在磁盘上。

这样它就会以最快的方式关闭,就在命令读取之后,而不是等待它完成任务(我只是做了一个测试:加密一些千兆字节并尝试读取命名管道(它&#39) ; s在进程列表中可见):即使openssl需要很长时间来加密,命名管道也会立即关闭。

关于您的评论

  

如果计算机已被第二个应用程序破坏以获得此功能   密码,然后用户担心一些严重的安全问题   关于。实际上,它可能是一些专门设计的软件   攻击我自己的软件

如果您的计算机遭到黑客攻击并且攻击者拥有相同的用户权限,那么您就完成了。例如,攻击者可以很容易地修改你的.bashrc到别名openssl,以便它启动一个hypotetic&#34; evil-openssl&#34;在将所有内容处理到真正的openssl之前复制您的密码和数据,让您产生错误的安全感。

那就是说,我不是安全专家,所以如果有人想要忘记我(并告诉我原因),那么欢迎您。

答案 2 :(得分:3)

If I understand right, your concert about

$ echo "someGoodPassword" | openssl (...) -pass stdin

is that the password will be visible in the process list to all users for some short amount of time. That can be easily worked around with bash's <<< redirection (will not work in plain old POSIX shell, though):

$ openssl (...) -pass stdin <<<"someGoodPassword"

This construct supports variable interpolation (<<<"$password") and the command output can be piped further or redirected to file as usual.

答案 3 :(得分:1)

将密码放入bash或其他脚本文件中,并为其创建600权限。这将只允许您查看该文件,并且密码不会在任何地方显示。

答案 4 :(得分:1)

您可以使用多种方法来输入密码:https://www.openssl.org/docs/man1.0.2/apps/openssl.html#PASS-PHRASE-ARGUMENTS

正如@Petesh所说,root可以读取所有内容!

因此,如果您将密码写下到任何common(!)文件中,例如

  • 进入具有安全权限的临时文件
  • 或在脚本中将echo欺骗到管道的内容是什么

root用户可以找到这个!

不喜欢使用/proc提供的所有功能(例如ps提供的功能)

所以,不要使用...

openssl aes-256-cbc ... -passin 'pass:someGoodPassword'

PASSWORD='someGoodPassword'
openssl aes-256-cbc ... -passin 'env:PASSWORD'`

最佳解决方案

  • 避免在系统上以纯文本格式存储密码(例如,使用密码管理器)
  • 通过管道/ fifo将密码传递到openssl

    password_manager get_password | openssl aes-256-cbc ... -passin 'stdin'
    

    # https://stackoverflow.com/a/7082184/1108919
    password_manager get_password >&3
    openssl aes-256-cbc ... -passin 'fd:3'
    

    openssl aes-256-cbc ... -passin "file:<(password_manager get_password)"