2013-06-17 4 views
11

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

Я создал следующий скрипт, который выполняет функцию захвата - это правильно в том смысле, что он хранит только переменную пароля в зашифрованном формате? Я обеспокоен тем, что пароль может быть доступен в памяти в другом месте (например, в $ _ хотя $ _ - 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'); 
+0

Вы должны, вероятно, проверить длину пароля и что означает '/ r'? –

+1

@mpapec '/ r' - неразрушающая подстановка, введенная в perl 5.14 (см. Perlop) - она ​​не изменяет строку на месте, но вместо этого возвращает измененную копию (очень удобная функция). – Xaerxess

+2

Кто вы пытаетесь защитить это? Если кто-то может заглянуть в память процесса, чтобы прочитать зашифрованный пароль, вы должны предположить, что они также могут прочитать ключ и источник вашей программы. Чтение пароля из stdin, а не как аргумент командной строки, будет защищать от случайных браузеров и, вероятно, лучшее, что вы можете ожидать. –

ответ

6

Это сложно.

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

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

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

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

3

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

+0

Пожалуйста, просветите меня, как я могу использовать OAuth для приложений командной строки? Особенно, если API, который OP обертывает, ожидает зашифрованный * пароль *? – amon

+0

Это, безусловно, возможно (у меня есть программы командной строки Twitter, которые используют OAuth), но настройка OAuth изначально может быть немного сложной и понадобится браузеру. Для примера см. Https://github.com/davorg/localtwits/blob/master/build.pl. Но даже если это было невозможно, это не повод для поощрения пользователей нарушить первое правило безопасности в Интернете. Никогда не делитесь паролем с третьим лицом. –

+0

Спасибо - использование этого подхода позволило бы устранить множество рисков безопасности. Я понимаю, что этого не было в моем сообщении, однако мне нужно создать XML-шаблон, который отправляется через https в сторонний API.Если сторонний API не поддерживает OAutho явно, могу ли я использовать его для решения этой проблемы? –

Смежные вопросы