![]() |
perl "password safe"-like program -- pws.pl
Hi,
On a Windows platform, I typically use the program "Password Safe" to keep all my passwords. But, as it only works on Windows, I was looking for a cross-platform solution. I wrote a program (below) that has the basic functionality of the program -- it stores your passwords in a database, encrypting both the keys (except the KEYCHECK key) and the values with blowfish. I guess someone could brute-force the password by encrypting the string "JUSTCHECKING" with blowfish, trying a bunch of different passphrases. How long would that take, assuming, say, an 16 characters passphrase? Also, the passphrase to encrypt/decrypt is obviously stored in memory. I don't think there's a way around this -- but how easy would it be to get it out of memory? AFAIK, the Windows version also stores the password in memory. I'm pretty new at perl, so I had hoped someone here could tell me whether my program really was as secure as I thought. The script is below. Hold no punches (polite punches appreciated :-D ), tell me how it is. What works, what doesn't work... whatever. ---BEGIN script--- #!/usr/bin/perl #------------------------------------------------------------------------ # pws.pl #"password safe"-like program in perl # released under the BSD license # Copyright (c) 2003, Robert Jacobson # All rights reserved. #------------------------------------------------------------------------ use Crypt::CBC; use Term::ReadKey; $SIG{INT} = clean_up; sub clean_up { print "Caught SIGINT, cleaning up...\n"; dbmclose(%PWS) or die "could not close database: $!"; ReadMode 0; exit; } # I have no idea how to use "tie", so I'm stuck with dbm... dbmopen(%PWS,"pws",0600) or die "Could not open database: $!"; # hash key by title, record contains # login, pass, notes(??) $JOIN = " "; # That's a tab, not a space #Check for correct password if ($PWS{KEYCHECK} eq "") { # New database $keymatch = 0; while ($keymatch == 0) { $key = ""; while (length($key) < 8) { print "Enter new database key: "; ReadMode 2; chomp($key = ReadLine); ReadMode 0; print "\n"; if (length($key) < 8) {print "Too short\n";} } print "Confirm database key: "; ReadMode 2; chomp($key2 = ReadLine); ReadMode 0; print "\n"; if ("$key" ne "$key2") { print "Keys don't match, try again\n"; } else { $keymatch = 1; } } print "Creating database..."; # Create a entry just for checking right key $plaintext = "JUSTCHECKING"; $cipher = Crypt::CBC->new( {'key' => "$key", 'cipher' => 'Blowfish'} ); $ciphertext = $cipher->encrypt($plaintext); $PWS{KEYCHECK} = "$ciphertext"; print "\n"; } else { # Existing database print "Enter key to database: "; ReadMode 2; chomp($key = ReadLine); ReadMode 0; print "\n"; # Check for right key $cipher = Crypt::CBC->new( {'key' => "$key", 'cipher' => 'Blowfish'} ); $plaintext = $cipher->decrypt($PWS{KEYCHECK}); if ($plaintext eq "JUSTCHECKING") { #print "That's right\n"; } else { print "incorrect key\n"; dbmclose(%PWS); exit; } } while (1) { print "Options:\n"; print "\t1. New Entry\n"; print "\t2. Read Entry\n"; print "\t3. Delete Entry\n"; print "\t4. Exit\n"; print "\nWhich? "; chomp ($choice = <STDIN>); if ($choice == 1) {&new_entry}; if ($choice == 2) {&read_entry}; if ($choice == 3) {&delete_entry}; if ($choice == 4) { dbmclose(%PWS); exit; } } sub new_entry { print "Enter title: "; chomp($title = <STDIN>); print "Enter login: "; chomp($login = <STDIN>); $match = 0; while ($match == 0) { $pass1 = ""; print "Enter pass: "; ReadMode 2; chomp($pass1 = ReadLine); ReadMode 0; print "\n"; print "confirm pass: "; ReadMode 2; chomp($pass2 = ReadLine); ReadMode 0; print "\n"; #confirm they match if ("$pass1" ne "$pass2") { print "They don't match,try again!\n"; } else { $match = 1; } } &encrypt_string; #Even the hash key (title) is encrypted $encrypted_title = $cipher->encrypt("$title"); $PWS { $encrypted_title } = "$ciphertext"; } sub read_entry { $showall = 0; print "Enter title (blank for all entries without passwords): "; chomp($title = <STDIN>); if ($title eq "") { $showall = 1; } else { $encrypted_title = $cipher->encrypt("$title"); } print "\n"; print "Title login\tpass\n"; print "----- -----\t----\n"; for $encrypted_titles (sort keys %PWS) { #print "key is $encrypted_titles\n"; next if $encrypted_titles eq KEYCHECK; unless ($showall) { #print "skipping\n"; next if "$encrypted_titles" ne "$encrypted_title"; } $plain_title = $cipher->decrypt("$encrypted_titles"); $plaintext = $cipher->decrypt("$PWS{$encrypted_titles}"); if ($showall) { # Dont show the password $plaintext =~ s/\t.*/\tHIDDEN/; } printf("%-21s%s\n",$plain_title,$plaintext); } print "\n"; } sub delete_entry { print "Enter title to delete: "; chomp($title = <STDIN>); $encrypted_title = $cipher->encrypt("$title"); delete($PWS { $encrypted_title }); } sub encrypt_string { # Blowfish encrypt the information $string_to_encrypt = "$login" . "$JOIN" . "$pass1"; $ciphertext = $cipher->encrypt("$string_to_encrypt"); return 1; } |
Re: perl "password safe"-like program -- pws.pl
Robert Jacobson <q2m3eft02@sneakemail.com> wrote in comp.lang.perl.misc:
> Hi, > > On a Windows platform, I typically use the program "Password Safe" to > keep all my passwords. But, as it only works on Windows, I was > looking for a cross-platform solution. > > I wrote a program (below) that has the basic functionality of the > program -- it stores your passwords in a database, encrypting both the > keys (except the KEYCHECK key) and the values with blowfish. I guess > someone could brute-force the password by encrypting the string > "JUSTCHECKING" with blowfish, trying a bunch of different passphrases. > How long would that take, assuming, say, an 16 characters passphrase? > > Also, the passphrase to encrypt/decrypt is obviously stored in memory. > I don't think there's a way around this -- but how easy would it be > to get it out of memory? AFAIK, the Windows version also stores the > password in memory. Sorry to be so blunt, but when you have to ask these questions on Usenet, you are not enough of a security expert to publish security-related software. The copyright and license comments in the code below makes me think you intend to distribute the program in some way. > I'm pretty new at perl, Another reason not to distribute sensitive software. > so I had hoped someone here could tell me > whether my program really was as secure as I thought. The script is > below. Hold no punches (polite punches appreciated :-D ), tell me how > it is. What works, what doesn't work... whatever. It is your program, and you will have to account for it. Even if someone here certified your program as flawless, (no-one sane will), what would you have gained? Use the program for yourself for a while. Try to crack it. Make it weaker until you *can* crack it. Read about computer security, if your interest goes that way. After a some of this you may develop a sense for the quality of your program. [code snipped] Anno |
| All times are GMT. The time now is 11:22 PM. |
Powered by vBulletin®. Copyright ©2000 - 2013, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.