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

Hi ! I have a little off-beat question about Crypt::DES. When I use crypting method of DES most of the times the string returned is same for example if I crypt 1 it returns (example) '3DfghjkloFXyD' most of the times this is not useful as it looses the purpose of Crypting I tried to change the key each time (it generated the differnt string but can not decrypt successfuly, so using random key does not work) Why this may be happening? Any solutions?

Replies are listed 'Best First'.
Re: Crypt::DES returns same string
by JayBonci (Curate) on Mar 30, 2002 at 21:50 UTC
    Well this is the basics of DES crypto. If you change the key, you're going to get a different output. This is sample code modified from the CPAN.org Crypt::DES documentation

    #!/usr/bin/perl -w use strict; use Crypt::DES; #Need a 16 byte key my $key = pack("H16", "0123456789ABCDEF"); my $cyp = new Crypt::DES $key; #and an 8-byte plaintext my $str = $cyp->encrypt("HelloWor"); my $uncyp = new Crypt::DES $key; print $uncyp->decrypt($str)."\n";


    How are you crypting 1? It's not 8 bytes long. 1111111 is however. Are you passing the key into the Crypt::DES new function? Are you using encrypt / decrypt per the documentation?

    Or are you using crypt? That's a built in perl function that probably isn't going to do what you want.

        --jb
Re: Crypt::DES returns same string
by Ryszard (Priest) on Mar 30, 2002 at 22:24 UTC

    I'm not sure what you are doing, but i get different ciphertexts for each plaintext:

    #!/usr/bin/perl -w use strict; use Crypt::DES; my $key = pack("H16", "hello"); my $cipher = new Crypt::DES $key; for (my $i=1;$i<11;$i++){ my $ciphertext = $cipher->encrypt(&pad($i)); print "ciphertext: ".unpack("H16", $ciphertext); print " plaintext : ".$cipher->decrypt($ciphertext)."\n"; } sub pad { my $padstr = shift; my $padlen = length($padstr); for (my $i=$padlen;$i<8;$i++) { $padstr = '#'.$padstr; } return $padstr; }

    Each pass produces the same ciphertext for each plaintext value:

    ciphertext: b9f13b4dadafc8a7 plaintext : #######1 ciphertext: a63ce27095356ceb plaintext : #######2 ciphertext: df037bd297aa73af plaintext : #######3 ciphertext: 0eaf7e009f26dc71 plaintext : #######4 ciphertext: 878da30ec4b03db2 plaintext : #######5 ciphertext: 38bb5f88a797e62e plaintext : #######6 ciphertext: e001696d8bcec155 plaintext : #######7 ciphertext: 6c3446a5cf32e3f2 plaintext : #######8 ciphertext: 21b4798bb48eb72d plaintext : #######9 ciphertext: 8ff59b7237d31c90 plaintext : ######10

    Random keys wont work unless you store the key somewhere, and associated it with the plaintext (or a hash of the plaintext), which in itself is bad security practise.

    Your comment of "most of the time" I think is inaccurate. If you use the same key on the same plaintext, you will _always_ get the same ciphertext. If you didnt, then what would happen if you gave someone your ciphertext and the key, and asked them to decrypt it? - it would produce the incorrect result.

    Check out Applied Cryptography. Its a fantastic book that explains symmetric (DES) and asymmetric (RSA) algorithms (among other things)..

    Are you able to explain the wider problem, or post a code snippit?

      Hi !

      Now I found the better words to explain my problem :) I was able to do crypting and decrypting. Now my requirement was to get different encoded string for the same 'plaintext' each time so people can not store these.

      I tried your code and ran 3-4 times each time it generates 'b9f13b4dadafc8a7' for plaintext '#######1'.(This is what my exact problem is. It generates same enoded string for given plaitext). Now what I want is lets say we have userid=1 then the encoded URL should send something.pl?userid=b9f13b4dadafc8a7 this is fine till this point.

      But I also want each time the script should create the encoded string for this userid (1 in our example) using crypting so as it does not match 'b9f13b4dadafc8a7' at least (Quasi random is fine)
      How do I get this using DES? So as user can not guess what the encoded string is for a given userid.

      Hope this explains what I want vs what I get clearly.

        Ahhhh ok, I think i'm begining to understand. DES cant do this. Given a key and plaintext, DES will always produce the same ciphertext.

        What I think you're after is session management.

        The basic gist is:

        1. You have already a bunch of users
        2. The user logs in and you give them a token
        3. Each page refresh you check their token against a list of known tokens. If its in the list, let them view the page, otherwise direct them to log in again

        The token can be an MD5 hash. The list of users can be in a database or in a flatfile, and you should have a sessions table (or ff) which would have the token and the user_id in it.

        Each page view you get the token (from a CGI param or from a cookie) and look it up in your session table.

Re: Crypt::DES returns same string
by no_slogan (Deacon) on Mar 31, 2002 at 17:23 UTC
    Use Crypt::CBC. It will automatically add a random IV to your message when you encrypt, so the same message won't encrypt to the same ciphertext. When you decrypt, it will automatically strip the IV and padding off the message. It also works with many different Crypt:: modules, so you can easily switch to a different cipher if you decide DES's 56-bit key is too short.
Re: Crypt::DES returns same string
by learn_forever (Acolyte) on Mar 30, 2002 at 22:06 UTC
    Thanks JB ! Well what if I am crypting the user ids say from 1 to 100000 which are integers? I am using Crypt::DES crypt and decrypt methods. And I tried to test this using standard 8 byte text (11111111) it still returns sane encrypted string. My question is how will I get the different encrypted strings each time? To my understanding I need to change the salt that's why I tried to change Key, (But it fails :) sorry for half-hearted tweaking) Can you suggest what would be olution? Thanks LF