2013-06-17 14 views
11

Produkuję moduł Perla, który zapewnia interfejs OO dla interfejsu API innej firmy. Chcę przechwycić i przechowywać hasło użytkownika w zaszyfrowanym formacie, zanim zostanie przesłane do interfejsu API innej firmy. Moduł jest przeznaczony do uruchamiania tylko w systemach UNIX.Haseł STDIN szyfrujących w języku Perl

Utworzono następujący skrypt, który wykonuje funkcję przechwytywania - czy jest to poprawne w tym sensie, że przechowuje tylko zmienną hasła w zaszyfrowanym formacie? Obawiam się, że hasło może być dostępne w pamięci w innym miejscu (np. Pod $ _ chociaż $ _ jest undef).

NB. Używam STDIN zamiast @ARGV z założeniem, że system operacyjny nie zarejestruje wpisu lub nie poda hasła w nazwie procesu. Używam zastępczego regex zamiast chomp, aby wejście nie musiało być przechowywane w tymczasowej niezaszyfrowanej zmiennej. Zakładam również, że nie można być całkowicie bezpiecznym w tym sensie, że oprogramowanie do przechwytywania wejścia może nadal przechwytywać dane wejściowe użytkownika.

góry dzięki

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

powinieneś prawdopodobnie sprawdzić długość hasła, a co oznacza '/ r'? –

+1

@mpapec '/ r' to niedestrukcyjne podstawienie wprowadzone w perlu 5.14 (patrz perlop) - nie modyfikuje łańcucha w miejscu, ale zamiast tego zwraca zmodyfikowaną kopię (bardzo przydatna funkcja). – Xaerxess

+2

Kogo próbujesz chronić? Jeśli ktoś może zajrzeć do pamięci procesu, aby odczytać zaszyfrowane hasło, należy założyć, że może również odczytać klucz i źródło twojego programu. Odczytywanie hasła ze stdin, a nie jako argumentu wiersza poleceń, chroni przed zwykłymi przeglądarkami i jest prawdopodobnie najlepszym, czego można się spodziewać. –

Odpowiedz

6

To trudne.

Uruchom swój kod szyfrujący jako oddzielny proces, element podrzędny kodu głównego, który to proces odczytuje ze STDIN i zwraca zaszyfrowane hasło (i być może klucz). W ten sposób kod wykorzystujący twój moduł sam w sobie nigdy nie utrzyma w pamięci zwykłego tekstu.

Oczywiście, śledzenie i kontrola pamięci (oraz kontrola pamięci po śmierci procesowej) pomocnika dziecięcego ujawni jawny tekst. Te same techniki ujawnią klucz i tekst zaszyfrowany odczytany również z pomocnika dziecięcego. Jeśli jednak scenariusz, w którym chcesz się bronić, to przypadkowe zatrzymanie jawnego tekstu w procesie - w złożonym obiekcie lub zamknięciu lub nie-wiem-a-temp-var-był-przydzielony-tam - wtedy wykonuj pracę w dedykowanym, krótkotrwałym procesie.

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

Nie sądzę, że można zapobiec kogoś z odpowiednimi uprawnieniami dostępu z wystającym wewnątrz połączeń systemowych lub pamięci.

3

Wygląda na to, że wdrażasz Password Anti-pattern. To okropny pomysł - uczy użytkowników być wyłudzonymi. Proszę tego nie robić. Zamiast tego powinieneś spojrzeć na użycie numeru OAuth.

+0

Proszę mnie poinformować, w jaki sposób mogę korzystać z protokołu OAuth w aplikacjach wiersza poleceń? Zwłaszcza jeśli API, które OP pakuje, oczekuje zaszyfrowanego * hasła *? – amon

+0

Jest to z pewnością możliwe (mam programy wiersza poleceń, które korzystają z protokołu OAuth), ale początkowo konfiguracja OAuth może być trochę skomplikowana i będzie wymagać przeglądarki. Zobacz przykład: https://github.com/davorg/localtwits/blob/master/build.pl. Ale nawet jeśli było to niemożliwe, nie jest to usprawiedliwieniem zachęcania użytkowników do łamania pierwszej zasady bezpieczeństwa w Internecie - nigdy nie udostępniaj hasła osobom trzecim. –

+0

Dzięki - stosowanie tego podejścia wyeliminowałoby wiele zagrożeń bezpieczeństwa. Zdaję sobie sprawę, że nie było to w moim poście, ale muszę wygenerować szablon XML, który jest wysyłany przez https do API strony trzeciej.Jeśli zewnętrzny interfejs API nie obsługuje jawnie OAutho, czy nadal mogę go użyć, aby rozwiązać ten problem? –