Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Perl > Perl Misc > perl "password safe"-like program -- pws.pl

Reply
Thread Tools

perl "password safe"-like program -- pws.pl

 
 
Robert Jacobson
Guest
Posts: n/a
 
      09-25-2003
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 ), 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) < {
print "Enter new database key: ";
ReadMode 2;
chomp($key = ReadLine);
ReadMode 0;
print "\n";
if (length($key) < {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;
}
 
Reply With Quote
 
 
 
 
Anno Siegel
Guest
Posts: n/a
 
      09-25-2003
Robert Jacobson <> 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 ), 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
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
FAQ 1.13 Is it a Perl program or a Perl script? PerlFAQ Server Perl Misc 0 04-11-2011 04:00 AM
FAQ 1.13 Is it a Perl program or a Perl script? PerlFAQ Server Perl Misc 0 01-20-2011 11:00 AM
Is it a Perl program or a Perl script? business one way Digital Photography 0 01-05-2008 04:40 PM
Perl 'system' Creates Program That Dies When First C Program Dies Christopher M. Lusardi Perl Misc 3 10-19-2003 11:53 AM
Perl Help - Windows Perl script accessing a Unix perl Script dpackwood Perl 3 09-30-2003 02:56 AM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57