Perl шифрование паролей STDIN

Я создаю модуль Perl, который предоставляет интерфейс OO для стороннего API. Я хочу захватить и сохранить пароль пользователя в зашифрованном формате, прежде чем он будет передан стороннему API. Модуль предназначен только для UNIX-систем.

Я создал следующий script, который выполняет функцию захвата - это правильно в том смысле, что он хранит только переменную пароля в зашифрованном формате? Я обеспокоен тем, что пароль может быть доступен в памяти в другом месте (например, в $_ хотя $_ - undef).

NB. Я использую 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');

Ответ 1

Это тяжело.

Запустите свой шифровальный код как отдельный процесс, дочерний элемент основного кода, который обрабатывает STDIN и возвращает зашифрованный пароль (и, возможно, ключ). Таким образом, код, использующий ваш модуль, сам по себе никогда не будет содержать открытый текст в памяти.

Проверка, отслеживание и проверка памяти (и проверка системной памяти после смерти процесса) дочернего помощника откроют открытый текст. В тех же методах будет отображаться ключевой и зашифрованный текст, прочитанные от дочернего помощника. Однако, если сценарий, против которого вы хотите защитить, - это случайное сохранение открытого текста в вашем процессе - в сложном объекте или закрытии или I-didn't-know-a-temp-var-was-alloc-there - then выполняйте работу в специализированном, недолговечном процессе.

Ответ 2

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

Я не думаю, что вы можете помешать кому-то с достаточными правами доступа заглянуть внутрь ваших системных вызовов или памяти.

Ответ 3

Похоже, вы реализуете "Антивирус паролей" . Это ужасная идея - она ​​учит пользователей фишинга. Пожалуйста, не делай этого. Вместо этого вы должны использовать OAuth.