Perl加密标准输入密码

11

我正在编写一个Perl模块,为第三方API提供面向对象的接口。在将用户密码传输到第三方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
2
@mpapec /r 是 Perl 5.14 中引入的非破坏性替换(参见 perlop)- 它不会直接修改字符串,而是返回一个修改后的副本(非常方便的功能)。 - Grzegorz Rożniecki
3
你试图保护这个密码不被谁看到?如果有人可以窥视进程内存并读取加密的密码,那么你必须假设他们也能读取密钥和程序源代码。从stdin中读取密码而不是作为命令行参数将防止随意浏览,这可能是你能期望的最好保护措施。 - evil otto
3个回答

9
$ strace perl -E '<STDIN>'
.... scroll, scroll, scroll ....
read(0, 
... type, type, type ....
"secret\n", 4096)               = 7
exit_group(0)                           = ?

我认为你无法阻止拥有足够访问权限的人查看你的系统调用或内存。


6

这很困难。

将加密代码作为主要代码的子进程单独运行,该进程从标准输入读取并返回加密密码(以及可能的密钥)。这样,使用您模块的代码本身将永远不会在内存中保存明文。

当然,跟踪和内存检查(以及进程死亡后的系统内存检查)子助手将显示明文。相同的技术也会显示从子助手读取的密钥和密文。但是,如果您希望防止在您的流程中意外保留明文:在复杂对象或闭包中,或者我不知道临时变量是否分配在那里 - 则在专用的短暂过程中完成工作。


3
听起来你正在实现密码反模式。那是一个可怕的想法-它教用户被钓鱼。请不要这样做。相反,你应该考虑使用OAuth

请告诉我如何在命令行应用程序中使用OAuth?特别是如果被包装的API需要加密的密码,该怎么办? - amon
当然可以(我有使用OAuth的命令行Twitter程序),但最初设置OAuth可能会有点复杂,并且需要浏览器。请参见https://github.com/davorg/localtwits/blob/master/build.pl以获取示例。但即使不可能,这也不是鼓励用户违反互联网安全第一规则 - 永远不要与第三方共享密码的借口。 - Dave Cross
谢谢 - 使用这种方法可以消除很多安全风险。我意识到这不在我的帖子中,但我需要生成一个XML模板,通过https发送到第三方API。如果第三方API没有明确支持OAutho,我仍然可以使用它来解决这个问题吗? - David Farrell
只有支持OAuth的服务才能使用OAuth。但是,您不应该要求用户为另一个服务提供其密码。 - Dave Cross
按照这个原则,该模块无法编写,因为所有API服务都需要经过身份验证的会话。 - David Farrell
@Sillymoose:听起来很有道理。但对你来说,什么更重要?编写此服务还是教用户互联网密码安全不重要?您可能会发现我在这个主题上的博客文章很有趣- http://blog.dave.org.uk/2012/03/internet-security-rule-one.html - Dave Cross

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接