Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked

Cookies & Encryption

by chiller (Scribe)
on Apr 14, 2002 at 21:56 UTC ( [id://159020]=perlquestion: print w/replies, xml ) Need Help??

chiller has asked for the wisdom of the Perl Monks concerning the following question:

I seem to be asking a bunch of questions lately (school project), but I can't seem to find any great source to tell me how to do this stuff:

I tried to encrypt a cookie (say I have a username that I want to save into a cookie, but I want to encode it somehow) using Crypt::CBC with Blowfish, which didn't work because of what looks like invalid characters (after all, it's a bunch of high ascii and whatnot).

I understand that people seem to do this with Digest::MD5? I don't have access to CGI Programming with Perl, but I do have the examples (I am still at something of a loss).

I think it's pretty clear how to encode something using Digest::MD5. How do I decode it? Am I just completely unclear on the concept? I know how to set a cookie and everything, just not encode/decode it properly.

Thanks a lot!

Replies are listed 'Best First'.
Re: Cookies & Encryption
by erikharrison (Deacon) on Apr 14, 2002 at 22:18 UTC

    You can't "decrypt" the Digest::MD5 encryption. The strings produced are not necessarily unique, meaning that if someone comes across the encrypted data they cannot turn it back into the original. The best use for this is too encrypt the key to a unique user in a server side database, and check that the encrypted cookie matches the encrypted key on the server, then give the submitting user access to the associated info. merlyn goes through the whole technique very thoroughly (and with many precautions and tricks that I haven't given you) in his Web Technique column. Check out

      So, if I understand you right, I should make a key using Digest::MD5, store it in a database, then insert this key into a cookie. Then check for its existence in a database? But then someone could edit their cookie and log in as any user?!

      I suppose if someone got that key out of the database it'd be bad. Is this about as secure as is typically necessary?

      Also it doesn't look like that article has much to do with encryption...

      The strings produced are not necessarily unique

      Erm, I think you may have MD5 mixed up with another algorithm.

      The whole point of one way hashes to to create a unique value that can be used to verify the original object.

        The whole point of one way hashes to to create a unique value that can be used to verify the original object.

        The whole point of one way hashes is to provide a function where it is impossible to determine the input given the output. While any given input will always have the exact same output every time, a one way hash does not guarantee that given all possible inputs there will be an equal number of outputs. Thus, the strings produced are not necessarily unique.

        For point of illustration, consider f(x) = 1. This is a one way hash. While not a very useful one, it does illustrate that not all values produced are unique.

Re: Cookies & Encryption
by chip (Curate) on Apr 15, 2002 at 00:01 UTC
    If you've got encrypted text and your only problem is that it's not plain ASCII, then just use unpack 'H*', $crypted to convert it to hex and pack 'H*', $cookie to bring it back.

        -- Chip Salzenberg, Free-Floating Agent of Chaos

Re: Cookies & Encryption
by stephen (Priest) on Apr 15, 2002 at 02:06 UTC

    MD5 is not an encryption algorithm. It's a fingerprinting system. If two pieces of data have the same MD5 fingerprint, it's very, very likely that they're the same. For example, the CPAN module uses MD5 to make sure (well, sort of sure) that the module that it just downloaded is the module that the author uploaded, and not some l33t d00d's attempt to break into your computer. MD5 is not in itself a digital signature system, though, since anyone can generate an MD5 digest of a piece of data. There is no secret key.

    In the past, I've created systems where one would store, say, the username in the cookie, plus a digest of the username plus some secret phrase. Anyone could read the cookie, but it would be slightly harder to tamper with it, since the hash would no longer match up.

    use strict; use Digest::MD5 qw(md5_base64); use constant SECRET_PHRASE => 'myzylplyk'; warn "This method is not secure!\n"; # Turn 'angela' into quasi-signed cookie my $cookie = generate_cookie('angela'); print "Cookie for 'angela' is: '$cookie'\n"; # Turn quasi-signed cookie back into angela print "Translating back: "; print "ok\n" if get_username($cookie) eq 'angela'; # See what happens if we turn angela into mary $cookie =~ s/angela/mary/; print "Gonna die now\n"; my $username = get_username($cookie); sub make_hash { my ($username) = @_; return md5_base64($username . SECRET_PHRASE); } sub generate_cookie { my ($username) = @_; my $enc_hash = make_hash($username); return "$username:$enc_hash"; } # Returns the username if all checks out, # dies horribly otherwise sub get_username { my ($cookie) = @_; my ($username, $digest) = split(/:/, $cookie); make_hash($username) eq $digest or die "Hack attack! Username '$use +rname' doesn't match hash\n"; return $username; }

    This method is NOT secure. Someone could sniff packets, read the cookie, and take over someone else's identity. You could add a timestamp to the cookie to patch it slightly... but it would still be possible to do some serious damage by simply grabbing a cookie and using it immediately. You could add an IP address, but... the list goes on and on.

    You'll probably do better using a Crypt:: module. You can use the MIME::Base64 module to translate the hi-ascii characters to something relatively web-safe. Or use HTTPS.


Re: Cookies & Encryption
by Ryszard (Priest) on Apr 15, 2002 at 02:03 UTC
    MD5 is known as a one way hashing algorithm. This means for all intents and purposes, you cannot reverse it. Similar algorithms include SHA1 and yes, unix crypt. There is an interesting metaphore of a one way function here.

    Web programmers use MD5 (or other one way functions) to create a unique string to use as a session id for that particular user. The session id is stored server side along with the user (name|id) and client side as the cookie value. Identification of the incoming user is done by retireving the cookie, looking it up in the "session table" then mapping it to the user.

    Have a look here, here, here and here for more information. There is also a node somewhere about storing information other than sess_id's in cookies, but i cant seem to find it anywhere...

    Update: I the node on storing data client side is here. Thx to wmono for a slight correction in my grammer.

Re: Cookies & Encryption
by ehdonhon (Curate) on Apr 15, 2002 at 03:24 UTC

    If you do not care how big your string is, you could always encrypt with whatever method you want and then use Base64 to encode your cyphertext into something that does not use high ascii.

Re: Cookies & Encryption
by Pahrohfit (Sexton) on Apr 15, 2002 at 14:01 UTC
    To encode:
    use Digest::MD5 qw( md5_hex ); my $public_part = "username"; my $secret_key = "foobar"; my $hash = md5_hex( join ':', $secret_key, md5_hex( join ':', $public_ +part , $secret_key ) ); my $session_key = "$public_part:$hash";
    To decode:
    use Digest::MD5 qw( md5_hex ); my $secret_key = "foobar"; my ( $username, $supplied_hash ) = split /:/, $session_key; unless ( ($enc_user =~ /^[a-zA-Z0-9_\%]+$/) && $supplied_hash =~ /^[0 +-9a-fA-F]{32}$/) ){ #err } my $hash = md5_hex( join ':', $secret_key, md5_hex( join ':', $usernam +e, $secret_key ) ); # Compare it to the hash they gave us. unless ( $hash eq $supplied_hash ) { #err }
    I would also percent encode/decode you cookie data before/after your md5.
Re: Cookies & Encryption
by wardk (Deacon) on Apr 15, 2002 at 15:26 UTC
    Sounds like your problem isn't really with encrypting, it's with saving the result as a cookie. If so, be sure to URLencode the result of the encryption before saving as a cookie, then URLdecode before unencrypting it.
Re: Cookies & Encryption
by perrin (Chancellor) on Apr 16, 2002 at 03:25 UTC
    The chapter of CGI Programming with Perl than you want is actually available for free.

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://159020]
Approved by chip
Front-paged by ehdonhon
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others goofing around in the Monastery: (3)
As of 2024-05-27 19:08 GMT
Find Nodes?
    Voting Booth?

    No recent polls found