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