2

I have a file with encrypted credentials with RC4, The piece of code in charge to write such credentials to the file is the following:

sub dummyFunction() {
    # Useless stuff for the scope of the problem
    # ...
    my $dbHost = "localhost";
    my $passphrase = "123"; # For example purposes, logic is different.
    my $cipher = Crypt::RC4->new($passphrase);
    return unpack('H*',$cipher->RC4($dbHost));
}

So that piece of code would return something like: 3F9FDCE3891C6B8851 but if I try the following:

sub anotherDummyFunction() {
    my $ciphered_text = &dummyFunction();
    my $passphrase = "123";
    my $cipher = Crypt::RC4->new($passphrase);
    print $cipher->RC4(pack('H*',$ciphered_text));
}

I am expecting to see localhost but instead, I get a bunch of bytes, so how would I get back the original text?

I already checked with a RC4 decryptor online, with my passphrase and my hex encoded string and the RC4 decryptor online does return localhost so I am sure that the encrypted string is right.

Thanks!

P.S.: The above example works in an isolated environment, but when it comes to my script it doesn't. I cannot get back the original string.

ILikeTacos
  • 17,464
  • 20
  • 58
  • 88
  • 2
    Don't show us example code that works and tell us that it doesn't work in some other context. The only thing we know is that the problem *isn't* in anything you've shown us. – hobbs May 10 '12 at 17:05
  • I'll use my psychic debugging skills to say that some whitespace has gotten into `$ciphered_text` in your actual script. `pack('H*',$ciphered_text)` does **not** pack just hexadecimal digits; it grabs the low 4 bits of each character in `$ciphered_text`, including whitespace characters. – cjm May 10 '12 at 17:55
  • I already found the root of the problem. At first I thought it was a whitespace, but it wasn't that. I was encrypting another string right before that one, but that one was being encrypted correctly. I had an epiphany and I thought that RC4 could be caching stuff, so I undef it, and it worked. – ILikeTacos May 10 '12 at 19:12
  • RC4 is a stream cipher, so of course `$cipher->RC4("encrypt-me")) x 2 ne $cipher->RC4("encrypt-me" x 2))`. If it were, a Boy Scout with a piece of paper and a pencil could break it. – cjm May 11 '12 at 01:58

1 Answers1

0

If anyone encounters this again:

If you have something like:


TEST.PL


 #!/usr/bin/perl
 use strict;
 use warnings;
 use Crypt::RC4;

 my $cipher = Crypt::RC4->new("passphrase123");
 print unpack('H*',$cipher->RC4("encrypt-me"))."\n";
 print unpack('H*',$cipher->RC4("encrypt-me"))."\n";

You will notice that you'll end up with two different encoded strings:

 ./test.pl
 25d2aa557cccc3951074
 1e87a5db7830a0b1cabd

In order to avoid this behavior I did:

undef $cipher

Right before trying to encrypt another string, and then instantiated the object again.

If you try this:

 my $cipher = Crypt::RC4->new("passphrase123");
 print unpack('H*',$cipher->RC4("encrypt-me"))."\n";
 undef($cipher);
 $cipher = Crypt::RC4->new("passphrase123");
 print unpack('H*',$cipher->RC4("encrypt-me"))."\n";

You'll get the same string:

./test.pl
25d2aa557cccc3951074
25d2aa557cccc3951074

this can also be wrapped in subprocedure, to avoid defining and undefining the object over and over.

sub encryptString()
{
    my ($string,$passphrase) = @_;
    my $cipher = Crypt::RC4->new($passphrase);
    return unpack('H*',$cipher->RC4($string));
}
ILikeTacos
  • 17,464
  • 20
  • 58
  • 88
  • 1
    Reading up on this stuff, came across this. A perl note: `undef($cipher);` is an unnecessary distraction. Remove it and the example runs with the same output shown (`25d2aa557cccc3951074` twice). The second `new` call is creating a "clean" `$cipher` so has the same content/output as the first. – Ashley Sep 19 '13 at 13:20
  • 1
    Thanks @Ashley. I remember posting this in my second day of working with Perl. I've learnt so much since then! – ILikeTacos Sep 19 '13 at 13:22