2012-08-03 20 views
5

Piszę skrypt Perl, który musi połączyć się z serwerem SMTPw celu wysłania poczty, ale ja naprawdę nie lubię tego rodzaju rzeczy:Jak mogę ukryć/chronić hasła ze skryptu Perl

my $pass = '123456'; 

i znalazłem Dane :: szyfrowane, który powinien umożliwić użytkownikowi poprosi go po raz pierwszy, a następnie zapisać go zaszyfrowane.

use Data::Encrypted file => ".passwd", qw(encrypted); 
my $password = encrypted('password'); 

Ale nie mogę zrobić to praca, to robi błąd czas trwania:

zły format pliku klucza w linii /Library/Perl/5.12/Data/Encrypted.pm 78

Czy ktoś ma ten sam problem lub zna inny sposób na ukrycie/ochronę hasła?

+3

nawet jeśli zadziała, jak zamierzasz odszyfrować? – pavel

+0

Może "md5" pomoże ci, sprawdzając sumę i wszystko ... – gaussblurinc

+0

Tak, też to widzę. Problem występuje w [Crypt :: RSA :: Key :: Private :: SSH :: deserialize line 68] (https://metacpan.org/source/VIPUL/Crypt-RSA-1.99/lib/Crypt/RSA/Key /Private/SSH.pm#L68). 'croak" Zły format pliku klucza "chyba że $ id eq PRIVKEY_ID;' ** $ id ** to '----- BEGIN PRYWATNY KLAWISZ RSA -----', ** PRIVKEY_ID ** to 'SSH PRYWATNE PLIK KLUCZA FORMAT 1.1 ". – daxim

Odpowiedz

8

Moduł Data::Encrypted został wydany po raz pierwszy w 2001 roku. Powiedziałbym, że to dobry znak, aby go nie używać.

Zazwyczaj powiedziałabym, że przechowywanie haseł jest złym pomysłem, nawet zaszyfrowanym. Jednakże, jeśli musisz przechowywać hasło do użytku, kontaktując się z innym systemem, szyfrowanie jest drogą do zrobienia. Sposób, zrobiłbym to jest coś takiego:

# Rijndael is also known as AES, which is the encryption standard used by the NSA 
use Crypt::Rijndael; 
use IO::Prompter; 

# This secret is exactly 32 bytes long, you could prompt for this as a 
# passphrase or something and pad it with spaces or whatever you need 
my $app_secret = 'this_is_the_key_the_app_uses....'; 

# Setup the encryption system 
my $crypto = Crypt::Rijndael->new($app_secret, Crypt::Rijndael::MODE_CBC()); 

# Ask the user to enter the password the first time 
my $password = prompt "password: ", -echo => ''; # from IO::Prompter 

# Encrypt the password. You can save this off into a file however you need to 
my $enc_password = $crypto->encrypt($password); 

# Later load it from the file and decrypt it: 
my $password = $crypto->decrypt($password); 

Więcej informacji można znaleźć Crypt::Rijndael i IO::Prompter.

+1

Trochę nie na temat, ale co z tego zyskujesz? Jeśli poprosisz o hasło, możesz równie dobrze poprosić o hasło bezpośrednio. A jeśli mocno zakodujesz hasło, nie pomoże to w ukryciu hasła "zaszyfrowanego". A może czegoś brakuje? – pavel

+0

Nie musisz pytać o hasło, to tylko jeden z możliwych sposobów zwiększenia bezpieczeństwa. Ponadto, jeśli istnieje wiele haseł do ochrony, jedno hasło jest łatwiejsze do wpisania i zapamiętania niż wiele haseł. – zostay

+0

Nawet bez hasła i po prostu przechowując sekret aplikacji w oddzielnym pliku, a nawet w samym skrypcie, można uniknąć przypadkowego odczytania prawdziwego hasła SMTP. Jeśli ktoś może ukraść plik haseł, ale nie uzyska sekretnej aplikacji, otrzymasz opóźnienie między kradzieżą hasła a złamaniem hasła. Jest dość cienki, jeśli chodzi o bezpieczeństwo, ale jest trochę lepszy niż nic. – zostay

2

Kiedy masz do czynienia ze skryptem, który wysyła hasło w postaci zwykłego tekstu do usługi bez interakcji użytkownika, jesteś już skazany na zagładę. Każde rozwiązanie, które przyjdzie Ci z pomocą, będzie tylko zabezpieczeniem przez zaciemnienie. Możesz przyjść z rozwiązaniem tak, jak zrobił to zostay. Ale jest to odpowiednik zakupu najbardziej zaawansowanego skarbca, ale pozwalając kluczowi pod matą i przyklejając papier z tekstem: "Sprawdź matę na klucz!" do drzwi wejściowych. Posłuchaj, po prostu skopiuję skrypt, grep na hasło. Potem znajdę linię, taką jak my $password = $crypto->decrypt($password); i umieszczę warn $password; tylko na linii poniżej i uruchom skrypt. to jest to! Nie obchodzi mnie, jakiego algorytmu używasz, nie obchodzi mnie, gdzie i jak przechowujesz hasło. Możesz uczynić mnie trudniejszym, ale mój wysiłek, by złamać, będzie zawsze o kilka rzędów wielkości mniejszy niż twój wysiłek, aby to utrudnić. Twój skrypt jest kluczem. Spójrz na cały ten przemysł filmowy. Wydali miliardy na nadchodzącą grupę głupich bzdur. Skończyło się na specjalnych HW, nawet kabel ma swój własny klucz. Wesoły! Nęka tylko uczciwych użytkowników.

Umieść zwykłe hasło w skrypcie, jeśli nie chcesz wyglądać głupio. Jeśli chcesz iść z bezpieczeństwem przez zaciemnienie, nie nadawaj nazw zmiennych o rozsądnych nazwach, nie używaj żadnego standardowego modułu (patrz, metoda decrypt to wskazówka!) I nie marnuj czasu na wyrafinowanie. Nie będę wyglądał, w jaki sposób przechowujesz lub zaszyfrujesz hasło, sprawdzę, gdzie będziesz musiał go użyć i zaczepisz. Jest o wiele łatwiej i trudniej się ukryć.

3

Dzięki! Oto moje ostateczne rozwiązanie:

sub smtp_passwd(){ 
    #The secret pass phrase 
    my $app_secret = 'd.<,3eJ8sh[(#@1jHD829J,Z!*dGsH34'; 

    #password file name 
    my $passwd_file_name = ".passwd"; 

    # Setup the encryption system 
    my $crypto = Crypt::Rijndael->new($app_secret, Crypt::Rijndael::MODE_CBC()); 

    #File Handler 
    my $passwd_file; 

    #If we cannot open the password file we initiate a new one 
    unless (open ($passwd_file, '<', $passwd_file_name)) { 

     #Create a new file in write mode 
     open ($passwd_file, '>', $passwd_file_name); 

     # Ask the user to enter the password the first time 
     my $password = prompt "password: ", -echo => ''; # from IO::Prompter 

     #Password must be multiple of 16 (we deliberately chose 16) 
     my $pass_length = 16; 

     #If password is to short we complete with blank 
     $password = $password." "x ($pass_length - length ($password)) if (length ($password) < $pass_length); 

     #If password is to long we cut it 
     $password = substr ($password, 0, $pass_length) if (length ($password) > $pass_length); 

     #Encryption of the password 
     my $enc_password = $crypto->encrypt($password); 

     #we save the password in a file 
     print $passwd_file $enc_password; 

     #we close the file (Writing mode) 
     close $passwd_file; 

     #Reopen the file in reading mode 
     open ($passwd_file, '<', $passwd_file_name) 
    } 

    #Loading the password en decrypt it 
    my $password = $crypto->decrypt(<$passwd_file>); 

    #Close the file 
    close $passwd_file; 

    #Return the password (Here the password is not protected) 
    return $password; 
} 
0

tutaj jest pełnowartościowy Kodeks który wykorzystuje część kodu wspomniano powyżej, a część pochodzi z Perlmonk. Skrypt najpierw prosi użytkownika o podanie nazwy użytkownika i hasła, szyfruje je i zapisuje w pliku .crypt. Następnie odczytuje z niego, odszyfrowuje i pokazuje oryginalny tekst. Za drugim razem użyje istniejących poświadczeń użytkownika.

use Crypt::Rijndael; 
use IO::Prompter; 
use Crypt::CBC; 
#keys 
my $key = "a" x 32; 
my $cipher = Crypt::CBC->new(-cipher => 'Rijndael', -key => $key); 
my @plaintext; 
my @ciphertext; 
#keys 

#filefield 
#password file name 
#my $file_name = ".crypt"; 
my $file_name = ".crypt"; 
#File Handler 
my $file; 


#If we cannot open the password file we initiate a new one 
unless (open ($file, '<:encoding(UTF-8)', $file_name)) { #<:encoding(UTF-8) 
#Create a new file in write mode 
    open ($file, '>', $file_name); 
    $plaintext[0]= prompt "Username:"; 
    $plaintext[1]= prompt "Password:", -echo => ''; 
    print "#################################################################################\n"; 
    print "# User credentials will be encrypted and stored in .crypt file and same is  #\n"; 
    print "# reused next time. If you need to add new user credentials delete the .crypt #\n"; 
    print "# file and re run the same script.            #\n"; 
    print "#################################################################################\n"; 
    $plaintext[0]=~ s/^\s*(.*?)\s*$/$1/; 
    $plaintext[1]=~ s/^\s*(.*?)\s*$/$1/; 


    while($plaintext[0] =~ /^\s*$/){ 
    $plaintext[0]= prompt "Username is mandatory:"; 
    $plaintext[0]=~ s/^\s*(.*?)\s*$/$1/; 
    } 
    while($plaintext[1] =~ /^\s*$/){ 
    $plaintext[1]= prompt "Password is mandatory:"; 
    $plaintext[1]=~ s/^\s*(.*?)\s*$/$1/; 
    } 


    $ciphertext[0] = $cipher->encrypt($plaintext[0]); 
    $ciphertext[1] = $cipher->encrypt($plaintext[1]); 

    #we save the password in a file 
    print $file $ciphertext[0]; 

    #print $file "\n"; 
    #we save the password in a file 
    print $file $ciphertext[1]; 
    #we close the file (Writing mode) 
    close $file; 

    #Reopen the file in reading mode 
    open ($file, '<', $file_name) 
} 


my @holder; 
my $content; 
if (open($file, '<', $file_name)) { 
    #chomp(@holder = <$file>); 
local $/; 
    $content = <$file>; 

} else { 
    warn "Could not open file '$filename' $!"; 
} 
@holder = split(/(?=Salted__)/, $content); 
    print "Encrypted username:",$holder[0]; 
    print "\n"; 
    print "Encrypted password:",$holder[1],"\n"; 

#Loading the password en decrypt it 
$plaintext[0] = $cipher->decrypt($holder[0]); 
$plaintext[1] = $cipher->decrypt($holder[1]); 

print "\n\n"; 

print 'Username is:',"$plaintext[0]\n"; 
print 'Password is:',"$plaintext[1]\n"; 
#Close the file 
close $file; 

#filefield 
Powiązane problemy