【问题标题】:Perl encrypting STDIN passwordsPerl 加密 STDIN 密码
【发布时间】:2013-06-13 18:40:34
【问题描述】:

我正在制作一个为第 3 方 API 提供 OO 接口的 Perl 模块。我想在将用户密码传输到第 3 方 API 之前以加密格式捕获和存储用户密码。该模块旨在仅在基于 UNIX 的系统上运行。

我制作了以下执行捕获功能的脚本 - 从某种意义上说,它仅以加密格式存储密码变量是否正确?我担心密码可能在其他地方的内存中可用(例如,在 $_ 下,尽管 $_ 是 undef)。

注意。我使用 STDIN 而不是 @ARGV 假设操作系统不会记录条目或在进程名称中包含密码。我使用的是替代正则表达式而不是 chomp,这样输入就不必存储在临时的非加密变量中。我还假设输入捕获软件仍然可以捕获用户的输入,因此不可能完全安全。

提前致谢

use strict;
use warnings;
use Crypt::CBC;
use 5.14.0;

print 'Please enter your password: ';
system('tty -echo');
my $key = Crypt::CBC->random_bytes(56);
my $iv  = Crypt::CBC->random_bytes(8);
my $cipher = Crypt::CBC->new(-key    => $key,
                             -cipher => 'Blowfish',
                             -salt   => 1,
                             );
my $ciphertext = $cipher->encrypt(<STDIN> =~ s/\n$//r);
system('tty echo');

【问题讨论】:

  • 您可能应该检查密码长度,/r 代表什么?
  • @mpapec /r 是 perl 5.14 中引入的非破坏性替换(参见 perlop) - 它不会修改字符串,而是返回修改后的副本(非常方便的功能)。
  • 你想保护谁?如果有人可以偷看您的进程内存以读取加密密码,则您必须假设他们也可以读取密钥和您的程序源。从标准输入读取密码而不是作为命令行参数读取密码可以防止普通浏览器,这可能是您可以期待的最好的。

标签: linux perl security unix encryption


【解决方案1】:
$ strace perl -E '<STDIN>'
.... scroll, scroll, scroll ....
read(0, 
... type, type, type ....
"secret\n", 4096)               = 7
exit_group(0)                           = ?

我认为您无法阻止具有足够访问权限的人窥视您的系统调用或内存。

【讨论】:

    【解决方案2】:

    这很难。

    将您的加密代码作为一个单独的进程运行,它是主代码的子进程,该进程从 STDIN 读取并返回加密的密码(可能还有密钥)。这样一来,使用你的模块的代码本身就不会在内存中保存明文。

    当然,子助手的跟踪和内存检查(以及系统进程死亡后的内存检查)将揭示明文。同样的技术也将揭示从儿童助手那里读取的密钥和密文。但是,如果您希望防御的场景是在您的过程中意外保留明文 - 在复杂对象或闭包中或 I-didn't-know-a-temp-var-was-allocated-there - 那么在一个专门的、短暂的过程中完成工作。

    【讨论】:

      【解决方案3】:

      听起来您正在实施Password Anti-pattern。这是一个可怕的想法——它教会用户被钓鱼。请不要那样做。您应该考虑改用OAuth

      【讨论】:

      • 请告诉我如何在命令行应用程序中使用 OAuth?特别是如果 OP 包装的 API 需要加密的 password?
      • 当然可以(我有使用 OAuth 的命令行 Twitter 程序),但最初设置 OAuth 可能有点复杂,需要浏览器。有关示例,请参阅github.com/davorg/localtwits/blob/master/build.pl。但即使不可能,这也不是鼓励用户打破互联网安全第一条规则的借口——永远不要与第三方共享密码。
      • 谢谢 - 使用这种方法可以消除很多安全风险。我意识到这不在我的帖子中,但是我需要生成一个 XML 模板,该模板通过 https 发送到第 3 方 API。如果 3rd 方 API 不明确支持 OAutho,我还能用它来解决这个问题吗?
      • 您只能将 OAuth 与支持 OAuth 的服务一起使用。但是,您永远不应该要求用户为您提供其他服务的密码。
      • 根据该格言,无法编写此模块,因为所有 API 服务都需要经过身份验证的会话。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-04-10
      • 1970-01-01
      • 2011-05-23
      • 2021-05-12
      • 2010-10-10
      • 2010-09-05
      • 2010-11-06
      相关资源
      最近更新 更多