Beefy Boxes and Bandwidth Generously Provided by pair Networks
more useful options
 
PerlMonks  

OpenSSL and Crypt::CBC don't give the same ciphertext

by LonelyPilgrim (Beadle)
on Feb 05, 2016 at 23:36 UTC ( [id://1154528]=perlquestion: print w/replies, xml ) Need Help??

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

Greetings, Wise Monks. I am a wayfarer returned from many travels.

I'm taking a Network Security course and am pretty much a novice when it comes to encryption. My assignment asks me to encrypt and decrypt a 1024-byte plaintext (which happens to be a transcript from the opening of Zork) by calling the OpenSSL binary -- but that's kind of slow, I suspect owing in part to the latency of launching new processes and file I/O, so I had (what I thought to be) the bright idea of doing the decryption separately in Perl (using Crypt::CBC) and timing the difference.

That's all well and good; doing it the Perl way appears to be considerably faster; but here's my problem: I can't get OpenSSL and Crypt::CBC to give me the same ciphertext. Can anybody help me figure out what I am doing wrong?

My code:

#!/usr/bin/env perl use strict; use warnings 'all'; my $test_in = 'test.txt'; my $test_out = 'test.bin'; my $cipher = 'des-cbc'; my $iv = '0123456789ABCDEF'; my $fixed_key = '0123456789ABCDEF'; open (my $infile, '<', $test_in) or die "Couldn't open $test_in for input: $!"; undef $/; my $plaintext = <$infile>; close ($infile); # OpenSSL my $enc = "openssl enc -$cipher -iv $iv -nosalt -out $test_out -K $fix +ed_key"; print "$enc\n"; open (my $pipe, "|-", $enc); print $pipe $plaintext; close $pipe; # Crypt::CBC require Crypt::CBC; require Crypt::Cipher::DES; $iv = pack("h*", $iv); $fixed_key = pack("h*", $fixed_key); my $crypt = Crypt::CBC->new( -cipher => 'Cipher::DES', -iv => $iv, -key => $fixed_key, -literal_key => 1, -header => 'none', ); my $ciphertext = $crypt->encrypt($plaintext); open (my $cipherout, '>', 'cryptx.bin') or die "Couldn't open cryptx.bin for output: $!"; binmode($cipherout); print $cipherout $ciphertext; close $cipherout;

Comparing test.bin (the output from OpenSSL) and cryptx.bin (the output from Perl) shows that the two are completely different from the first byte. The files are the same length (1032 bytes) and do not change with each run.

UPDATE: I fixed it. Oh, I'm an idiot. Endianness: so simple and yet so important. It should have been H* instead of h* in my pack statements. Fix that, and it gives the right result.

Replies are listed 'Best First'.
Re: OpenSSL and Crypt::CBC don't give the same ciphertext
by syphilis (Archbishop) on Feb 06, 2016 at 02:24 UTC
    UPDATE: I fixed it .... It should have been H* instead of h* in my pack statements

    On my Windows machine I find that it does indeed need to be "H*".
    I also need to binmode $pipe if I want test.bin and cryptx.bin to agree.
    The contents of those 2 files will change (but still be in agreement) depending upon whether I binmode $infile.
    The binmode $infile therefore apparently affects what is fed in - but, as you observed, both ciphers will receive identical inputs in any case.

    I think (untested) you might be able to avoid the binmode calls if you're not on Windows.

    Cheers,
    Rob

      syphilis : I think (untested) you might be able to avoid the binmode calls if you're not on Windows.

      :D how many thousands of times have you seen the solution to a problem was a missing call to binmode?

      binmode on linux, binmode on windows, binmode always :D

        how many thousands of times have you seen the solution to a problem was a missing call to binmode?

        I've seen that lots of times .... on Windows ;-)

        Cheers,
        Rob
Re: OpenSSL and Crypt::CBC don't give the same cipher text
by Anonymous Monk on Feb 06, 2016 at 01:54 UTC
    $iv = pack("h*", $iv); $fixed_key = pack("h*", $fixed_key);
    Is that correct? How does openssl interpret iv and key strings? Note that "With format "h", the first character of the pair determines the least-significant nybble of the output character"
    $ perl -E 'say ord pack "h*", "01"' 16 # that is, 0x10 $ perl -E 'say ord pack "H*", "01"' 1
      Thanks. This was indeed the problem. I realized it myself around the same time you posted your comment.
Re: OpenSSL and Crypt::CBC don't give the same cipher text ( binmode )
by beech (Parson) on Feb 06, 2016 at 00:08 UTC
    Add binmode $infile; and see what happens
      Thanks, but that doesn't make any difference. In any case, even if my input was somehow being corrupted (it was plain ASCII text), it was the same input being fed into both OpenSSL and Crypt::CBC.

        Thanks, but that doesn't make any difference. In any case, even if my input was somehow being corrupted (it was plain ASCII text), it was the same input being fed into both OpenSSL and Crypt::CBC.

        Also try  binmode $pipe; :)

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others admiring the Monastery: (5)
As of 2024-03-19 10:33 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found