web-security methods, advice please!

Madison Kelly linux-5ZoueyuiTZhBDgjK7y7TUQ at public.gmane.org
Mon Jan 1 00:53:42 UTC 2007


Hi all,

   I asked this earlier on TPM who've provided some great feedback. Now 
I though I'd like to get feedback from the (more diverse) TLUG peoples. :)

   (Perl) Code below.

   I've started a web-based CRM program for my new company and so I am 
more concerned with security than I have needed to be in the past. I was 
hoping to run down my current plan to see what TLUG'ers think.

   I am not a cryptologist (or particularly good at math) and make no 
claims to be a security expert of any kind. So please be brutal and 
honest with my plans (a cracker would)! :)

- Two steps; 1. password authentication and 2. Cookie sessions.

Password;

- When a user creates (or changes) their password, they send to the 
server their desired password.
   - Being a new password, I generate a 36 byte 'salt' string and store 
this string in the database.
   - I run their password through SHA256 to get an unpadded base64 hash
   - I stick the salt onto this initial hash which I call my 'weak_key'.
   - I then generate a new (base64 SHA256) hash which I call the 'weak_hash'
   - I take this 'weak_hash', prefix the salt string and generate a new 
SHA256 base64 hash. I repeat this step 40,000+ times on my old laptop 
(will do it more on the server when I am done). (reasoning behind this 
step here: http://en.wikipedia.org/wiki/Key_strengthening ).

- When a user logs in later their password is again sent to the server.
   - This time though the salt string is read from the DB and then all 
the steps above are repeated to see if the same hash value is created.

Cookie;

- Once a user successfully logs in, I set a cookie with their user ID 
number and a session hash.
   - To create this session hash I create a random number and store it 
in the database. I look at the current date on the server and then I 
combine: [UID + Random # + Date + Client UA + Client IP Address] and 
create a simple SHA256 base64 hash.

- After this, each time the user calls the program, I:
   - Read their UA string and their IP address.
   - Get the random number out of the DB.
   - Check the current and previous date from the server.
   - Read the UID and session hash from the client's cookie.
   - Generate two hashes like I did above (one or today and yesterday's 
date) and check to see if either match the session hash. If so, the 
session is valid. If the previous date's hash matched, I update the 
session hash (to account for people working over midnight server-time).


   The salt string is a 36-byte string of alternating non-alphanumberic 
characters -> digits -> mixed-case letters. The salt is changed whenever 
the password is (re)set.

   I plan to use SSL to prevent sniffing but I don't know enough about 
cross-site scripting attacks to know how to properly defend against them.

   Below is the test program I wrote for generating the password hash. I 
am still working on the cookie code so I can't post that yet.

Again, *Please* be brutal on your critiques of my methods. If my 
thinking is flawed, I would be grateful to learn now rather than later. :)

   Also, I don't believe in security through obscurity in the slightest, 
so if my methods can't survive being exposed, I'd also rather know now. :)

Thanks as always!!

Madison

-=] Code [=-
#!/usr/bin/perl -T

use strict;
use warnings;

use Digest::SHA qw(sha256 sha256_hex sha256_base64);
use Time::HiRes qw(usleep ualarm gettimeofday tv_interval);

my $t0 = [gettimeofday];

my $msg=$ARGV[0];
my @seed=(" ", "~", "`", "!", "\@", "#", "\$", "\%", "^", "&", "*", "(",
")", "-", "_", "+", "=", "{", "[", "}", "]", "|", "\\", ":", ";", "\"",
"'", ",", "<", ".", ">", "/", "?");
my @alpha=("a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l",
"m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z",
"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N",
"O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "G");
my $seed_num=@seed;
my $alpha_num=@alpha;
my $hash_reiteration=32000;

# Generate a new salt string (will use later when new passwords are saved).
my $salt;
for (1..12)
{
	$salt.=$seed[int(rand($seed_num))];
	$salt.=int(rand(10));
	$salt.=$alpha[int(rand($alpha_num))];
}

# SHA256
print "-=] SHA256 [=-\n";
$t0 = [gettimeofday];

my $weak_key=sha256_hex($msg);
$weak_key.=$salt;
my $weak_hash=sha256_base64($weak_key);

print "Initial hashes generated in: [".tv_interval($t0)."] seconds.\n";
print "Seeds: [$seed_num], 'msg': [$msg], 'salt': [$salt]\n";
print "SHA_base64 of: [$weak_key]\n";
print "           is: [$weak_hash]\n";

# Now reinforce the hash
my $strong_hash=$weak_hash;
for (1..$hash_reiteration)
{
	$strong_hash=sha256_base64($salt.$strong_hash);
}
print "Strong hashes generated in: [".tv_interval($t0)."] seconds.\n";
print "Strong Hash of: [$weak_hash]\n";
print "            is: [$strong_hash]\n";

exit(0);
-=] Code [=-


-=] Sample run [=-
digimer at akane:~/an_sdb/cgi-bin$ ./test.pl foobar
-=] SHA256 [=-
Initial hashes generated in: [0.000257] seconds.
Seeds: [33], 'msg': [foobar], 'salt': [*6w:7W=2k^4b]4k>4t 0W/7g&7t_7M\7k<3s]
SHA_base64 of:
[c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2*6w:7W=2k^4b]4k>4t 

0W/7g&7t_7M\7k<3s]
            is: [TsE7D2Q20LGLAH9hDJxDzOoADIgUdhZ++z6BKhHm8vE]
Strong hashes generated in: [0.757067] seconds.
Strong Hash of: [TsE7D2Q20LGLAH9hDJxDzOoADIgUdhZ++z6BKhHm8vE]
             is: [HaKr67EEQuSXR8nT7XNrECSy4eFvKZyDQcag0sI1SSA]
-=] Sample run [=-
--
The Toronto Linux Users Group.      Meetings: http://gtalug.org/
TLUG requests: Linux topics, No HTML, wrap text below 80 columns
How to UNSUBSCRIBE: http://gtalug.org/wiki/Mailing_lists





More information about the Legacy mailing list