[英]How could I hide/protect password from a Perl script
我正在編寫一個需要連接到SMTP服務器才能發送郵件的Perl腳本 ,但我真的不喜歡這樣的東西:
my $pass = '123456';
我找到了Data :: Encrypted ,它應該允許用戶第一次提示它然后加密存儲它。
use Data::Encrypted file => ".passwd", qw(encrypted);
my $password = encrypted('password');
但我無法使它工作,它會導致運行時錯誤:
/Library/Perl/5.12/Data/Encrypted.pm第78行的密鑰文件格式錯誤
有人有同樣的問題,或者知道隱藏/保護密碼的其他方法嗎?
Data :: Encrypted模塊最后一次發布於2001年。我想說這是一個不使用它的好兆頭。
通常情況下,我認為存儲密碼甚至是加密的壞主意。 但是,如果您必須存儲密碼以便與其他系統聯系使用,則可以對其進行加密。 我這樣做的方式是這樣的:
# 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);
有關更多信息,請參閱Crypt :: Rijndael和IO :: Prompter 。
當您處理一個腳本,該腳本在沒有任何用戶交互的情況下向服務發送純文本密碼時,您已經注定失敗了。 您將帶來的任何解決方案都只是默默無聞的安全性。 你可以像zostay那樣提供解決方案。 但這相當於購買了最先進的保險庫,但卻把鑰匙放在墊子底下並貼上了文字:“檢查墊子上的鑰匙!” 到前門。 看,我將只復制腳本,grep為密碼。 然后我會發現像my $password = $crypto->decrypt($password);
並warn $password;
就在下面的行並運行腳本。 而已。 我不關心你使用什么算法,我不關心你在哪里以及如何存儲密碼。 你可以讓我更難,但我的努力破解總是比努力努力的幾個數量級。 你的腳本是關鍵。 看看這個電影業。 他們花了數十億美元與一堆愚蠢的垃圾一起來。 他們最終得到了特殊的硬件,甚至電纜都有自己的密鑰。 爆笑! 它只是騷擾公平的用戶。
如果您不想看起來很傻,請在腳本中放置普通密碼。 如果你想通過默默無聞的安全性,那么不要使用合理的名稱命名變量,不要使用任何標准模塊(外觀,方法decrypt
是線索!)並且不要浪費你的時間與復雜性。 我不會看你如何存儲或加密密碼,我會看看你將在哪里使用它並掛鈎。 隱藏起來要容易得多,也要難得多。
謝謝 ! 這是我的最終解決方案:
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;
}
這里是完整的代碼,它使用了上面提到的部分代碼和部分代碼來自Perlmonk。 該腳本首先詢問用戶的用戶名和密碼,加密並將其存儲在.crypt文件中。 然后從中讀取,解密並顯示原始文本。 第二次它將使用現有的用戶憑據。
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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.