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

I am having an issue with the below script. The intent of the script is to input an encryption key and a text file and then use the TEA algorithm to encrypt the contents. For whatever reason, my code or the module is failing to work properly with a text file that contains more than 32 characters before a line break. I am not real sure how to fix this, I was hoping someone could help me out. Thanks in advance.
#!/usr/bin/perl -w use strict; use warnings; use Crypt::Tea; if (@ARGV != 3) { print STDERR "Usage: $0 [-d|-e] [FILENAME] [KEY] \n"; exit 1; } if (($ARGV[0] ne '-d') && ($ARGV[0] ne '-e')) { print "Specify '-d' to decrypt or '-e' to encrypt\n"; exit 1; } my ($action, $file, $key) = @ARGV; open (my $fh, '<', $file) or die $!; my @input = readline($fh) or die "readline failed: $!\n"; if ($action eq '-e') { my @cryptedText = cryptText($key,$action,\@input); my $i = join("\n",@cryptedText); print $i; } if ($action eq '-d') { my @cryptedText = cryptText($key,$action,\@input); my $i = join('',@cryptedText); print $i; } sub cryptText { die if @_ != 3; my ($key,$action,$input) = @_; my @cryptedText; foreach my $text (@$input) { if ($action eq '-d') { $text = decrypt($text,$key); } if ($action eq '-e') { $text = encrypt($text,$key); } push (@cryptedText,$text); } return @cryptedText; }

Replies are listed 'Best First'.
Re: 32 Character limit
by ikegami (Patriarch) on Feb 09, 2011 at 00:27 UTC

    That's a very unsafe way of doing things! You should be calling encrypt once, not once per line.

    encrypt(join("\n", @$input), $key)

    I do get garbage at character 32 (or thereabouts, I didn't look closely) when I use your version. I didn't spend any time finding out why because it goes away if you encode once as I urged you to do above.

    ... my ($action, $file, $key) = @ARGV; my $input; { open(my $fh, '<', $file) or die("Can't open $file: $!\n"); binmode($fh); local $/; $input = <$fh>; } if ($action eq '-e') { print encrypt($input, $key); } else { print decrypt($input, $key); }
    $ diff -au a.pl <( perl a.pl -d <( perl a.pl -e a.pl key ) key ) $

      Thanks for the replies. However I am not sure I understand. Isn't my code

      if ($action eq '-e') { my @cryptedText = cryptText($key,$action,\@input); my $i = join("\n",@cryptedText); print $i; }

      Only calling cryptText (my encrypt sub) one time? It is then joining the newline characters to the end, because when I didn't it would fail to encode properly. Maybe I am missing the boat here.. Please explain

        Isn't my code only calling cryptText (my encrypt sub) one time?

        No, once for each element in @$input.

        foreach my $text (@$input) { ... $text = encrypt($text,$key); ... }
Re: 32 Character limit
by jethro (Monsignor) on Feb 08, 2011 at 23:43 UTC

    The documentation of Crypt::Tea says about encrypt: " Encrypts blocksize() bytes of $data and returns the corresponding ciphertext.". Similar for decrypt.

    Sounds like you have to split the input data into chunks of blocksize() length and feed that to the functions

      Where do you see that? The version on CPAN doesn't say that at all. It simply says "Encrypts with CBC (Cypher Block Chaining)". CBC is most desirable and impossible if you split the input data in chunks of blocksize.

      Update: Ah! You seem to be talking of Crypt::TEA. That's not the module the posted code is using. One should use Crypt::TEA via Crypt::CBC. It is much less secure to split the input into blocksize chunks.

      Note that Crypt::TEA and Crypt::Tea cannot both be installed on a case-insensitive file system, and attempting to load one may load the other.