in reply to Base64 Encoded cookie is giving me headaches!

Viewing the decoded string in the debugger, it appears that all the data is there...

The first 8 bytes are probably the two dates, perhaps packed seconds since epoch. unpack those and convert them to dates with localtime. The remaining data is null-separated; split /\0/ to get the remaining fields. The last one does appear to be an MD5 hash, as you said.

Update: How about a code example? :)

#!/usr/local/bin/perl -w use strict; use CGI qw/:standard/; use CGI::Carp qw(fatalsToBrowser); use MIME::Base64; use CGI::Cookie; my $query = new CGI; my %cookies = fetch CGI::Cookie; my $cookie = $cookies{'Cookie-Name'}->value; print $query->header; print $query->start_html; print "<h1>Cookie</h1><br>\n"; print "Straight cookie: $cookie\n<br><br>\n"; my $decoded = decode_base64($cookie); my($time1, $time2) = unpack 'NN', $decoded; substr($decoded, 0, 8) = ''; print join "<BR>", "Decoded cookie:", scalar(localtime $time1), scalar(localtime $time2), split /\0/, $decoded; print $query->end_html;

Replies are listed 'Best First'.
Re: Re: Base64 Encoded cookie is giving me headaches!
by tame1 (Pilgrim) on Mar 17, 2001 at 01:40 UTC
    Here is their web page (at least the part I can release)

    Each cookie contains the following fields:

    Issue Time Expire Time Issuer Userid IP Address ACIGROUP Location Other Data Signature
    Issue Time
    The time when the cookie was issued.
    Expire Time
    The time when the cookie will no longer be valid.
    Issuer
    The name of the issuer of the cookie.
    Userid
    The userid represented by the cookie.
    IP Address
    The IP address for which the cookie is valid.
    ACIGROUP
    The security group from PROFS for the user. This is useful to determine if the user is a dealer or supplier.
    Location
    The location code for suppliers. This is not useful inside the Company.
    Other Data
    Other fields may be defined in the future.
    Signature
    The RSA encrypted MD5 digest of the rest of the cookie.

    Security of the System


    The security of the system resides in the use of public key cryptography to digitally sign the cookie. The issuer of the cookie computes a special checksum of the cookie (using the RSA Data Security, Inc. MD5 Message-Digest Algorithm) and then encrypts this checksum with the issuer's private key. The issuer is the only holder of the private key.

    The receiver looks up the issuer's public key, and decrypts the checksum. The receiver compares this checksum with one that it computes, and compares the two. If they are equal, then:

    • The cookie was issued by the issuer, and
    • The cookie has not been tampered with.

    Web Single Logon's private keys are kept on a secured server. The public key is distributed with the Web Single Logon kit. A trust relationship is established with the issuer. When the cookie is validated, and has not expired, then the identity encoded in the cookie is trusted. This establishes the logon.


    Password Validation


    Centralizing the logon process allows a great flexibility in maintaining a central Web password database. The Web Single Logon Password Server currently uses the PROFS systems or X.500 for non-profs users to validate logons. This gives Web Single Logon secured servers access to a base of over 95,000 users.



    What does this little button do . .<Click>; "USER HAS SIGNED OFF FOR THE DAY"
      Okay, here's some pseudo-code which I think is the right way to use the last value in the null-separated string of values:
      use Some_RSA_Module; use Digest::MD5 qw/ md5 /; # decode base64 as before, then: my $encrypted = substr($cookie, -64); substr($cookie, -65) = ''; # strip the null and the security fiel +d my $checksum = Some_RSA_Module::unencrypt($some_public_key, $encrypted +); my $new_checksum = md5($cookie); if ($new_checksum eq $checksum) { print "Checksums match, cookie data is valid.\n"; } else { print "Checksums don't match, cookie data has been tampered with.\n" +; }
      Obviously, I don't know how to do the actual decryption of the security field. :)

      The other question is how the md5 hash is being generated; they could be used md5_base64 or md5_hex instead of plain md5. The length of the decrypted checksum will tell you which...

      I used substr() to get the security field, instead of splitting on nulls, because I was cautioned in the CB that the security field might contain embedded nulls itself. :)