I am creating a website which will cater for several clients, each of whom will have several users.
To keep life simple I will create a database for each client and all the relevant stuff will go in there. There will also be a master database that stores only the information that is needed to get the user to the right database at login.
The users will be given sessions (stored in cookies) which say not only who they are but also which database they should connect to. Once the database has been determined the session_id and session_secret will be used to check that the user is allowed.
The attached code is my attempt to prevent tampering of that cookie. It is cut back so that only the relevant bits are presented. I am fairly sure that it is secure but I cannot be sure.
Please could you look at this code and see if there are any holes. Thank you.
#!/usr/bin/perl use strict; use warnings; use String::CRC::Cksum qw(cksum); use Crypt::CBC; # Utility function. sub display { my ( $first, $second ) = @_; print ' 'x( 16 - length $first ), "$first: '$second'\n"; } my $database_id = 1234; my $session_id = 5678; my $session_secret = join '', 'a'..'z'; # Create the input. my $in = join ':', $database_id, $session_id, $session_secret; display "Input", $in; my $cipher_text = my_encrypt( $in ); display "Encrypted token", $cipher_text; # $cipher_text =~ s/a/b/g; # <= uncomment to muck up the encryption. # display "Altered token", $cipher_text; my $out = my_decrypt( $cipher_text ); display "Output", $out; display 'Result', $in eq $out ? "Good" : "Bad"; ############################################## sub my_encrypt { my $input = shift || die; # Calculate the checksum and then prepend it to the token. my $cksum = cksum( $input ); my $token = join ':', $cksum, $input; display "Token", $token; # Encrypt the token to hex. my $cipher = get_cipher(); my $hex_token = $cipher->encrypt_hex( $token ); return $hex_token; } sub my_decrypt { my $input = shift || die; my $cipher = get_cipher(); my $cksum_token = $cipher->decrypt_hex( $input ); display "Decrypted token", $cksum_token; unless ( $cksum_token ) { warn "Error decrypting"; return 0; } # Extract the checksum and then check it. my ( $cksum, $token ) = split /:/, $cksum_token, 2; # If the checksum is correct. return $token if defined $cksum && $token && $cksum =~ m/^\d+$/ && cksum( $token ) == $cksum; # If it is not correct then complain. warn "Checksum is wrong."; return 0; } sub get_cipher { my $system_secret = 'top secret'; return Crypt::CBC->new ( {'key' => $system_secret, 'cipher' => 'Blowfish' } ) || die; }
--tidiness is the memory loss of environmental mnemonics
In reply to Is this a secure way to prevent cookie tampering by EvdB
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |