2013-06-17 3 views
11

Sto producendo un modulo Perl che fornisce un'interfaccia OO per un'API di terze parti. Voglio acquisire e archiviare la password dell'utente in un formato crittografato prima che venga trasmessa all'API di terze parti. Il modulo è progettato per essere eseguito solo su sistemi basati su UNIX.Perl codifica password STDIN

Ho prodotto il seguente script che esegue la funzione di acquisizione: è corretto nel senso che memorizza solo la variabile password in un formato crittografato? Sono preoccupato che la password possa essere disponibile in memoria altrove (ad esempio sotto $ _ anche se $ _ è undef).

NB. Sto usando STDIN piuttosto che @ARGV con il presupposto che il sistema operativo non registra la voce o include la password nel nome del processo. Sto usando una regex sostitutiva piuttosto che chomp in modo che l'input non debba essere memorizzato in una variabile temporanea non crittografata. Suppongo anche che non sia possibile essere completamente sicuri nel senso che il software di acquisizione di input possa ancora catturare l'input dell'utente.

Grazie in anticipo

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

probabilmente dovresti controllare la lunghezza della password, e cosa significa '/ r' sta per? –

+1

@mpapec '/ r' è una sostituzione non distruttiva introdotta in perl 5.14 (vedi perlop) - non modifica la stringa sul posto ma restituisce invece una copia modificata (funzione molto utile). – Xaerxess

+2

Chi stai cercando di proteggere da questo? Se qualcuno può dare un'occhiata alla memoria del processo per leggere la password crittografata, si deve presumere che possano leggere anche la chiave e la fonte del programma. Leggere la password da stdin piuttosto che come argomento da riga di comando proteggerà dai browser casuali ed è probabilmente la migliore che ci si possa aspettare. –

risposta

6

È difficile.

Eseguire il codice di crittografia come processo separato, figlio del codice principale, quale processo legge da STDIN e restituisce la password crittografata (e probabilmente la chiave). In questo modo, il codice che usa il tuo modulo non conserverà mai il testo normale in memoria.

Certo, tracciamento e controllo della memoria (e sistema ispezione di memoria dopo la morte del processo) del child helper rivelerà il testo in chiaro. Le stesse tecniche rivelano la chiave e il testo cifrato letti anche da un assistente figlio. Tuttavia, se lo scenario contro il quale desideri difendere è la conservazione accidentale del testo in chiaro nel tuo processo - in un oggetto complesso o in una chiusura o I-didn't-know-a-temp-var-was-allocate-lì - allora fare il lavoro in un processo dedicato, di breve durata.

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

non credo che si può evitare che una persona con diritti di accesso sufficienti da sbirciare dentro le chiamate di sistema o di memoria.

3

Sembra che tu stia implementando lo Password Anti-pattern. È un'idea terribile: insegna agli utenti di essere phishing. Per favore, non farlo. Si dovrebbe guardare usando OAuth invece.

+0

Per favore chiariscimi come posso usare OAuth sulle applicazioni della riga di comando? Soprattutto se l'API con cui si sta eseguendo l'OP si aspetta una password * cifrata *? – amon

+0

È certamente possibile (ho programmi Twitter a riga di comando che usano OAuth) ma inizialmente impostare OAuth può essere un po 'complesso e richiederà un browser. Vedi https://github.com/davorg/localtwits/blob/master/build.pl per un esempio. Ma anche se fosse impossibile, non è una scusa per incoraggiare gli utenti a infrangere la prima regola della sicurezza di Internet - Non condividere mai una password con una terza parte. –

+0

Grazie - l'utilizzo di questo approccio eliminerebbe molti rischi per la sicurezza. Mi rendo conto che questo non era nel mio post, tuttavia ho bisogno di generare un modello XML che viene inviato tramite https all'API di terze parti.Se l'API di terze parti non supporta OAutho esplicitamente, posso ancora utilizzarlo per risolvere questo problema? –