-1

I cannot get Perl and Ruby to agree on CBC AES:

Perl

use Crypt::CBC;
use MIME::Base64::Perl;

my $cipher = Crypt::CBC->new(
        -key         => 'd2cb415e067c7b13',
        -iv          => 'e36dc751d0433f05', #random 16chars!!!!!! shold NOT repeat between requests
        -cipher      => 'OpenSSL::AES',     #this is same as Rijndael
        -literal_key => 1,        
        -header      => "none",
        -keysize     => 16
  );  

$encypted = $cipher->encrypt("a really really long long text has differrent results???");
$base64 = encode_base64($encypted);

print("Ciphertext(b64): $base64");

$de_base64 = decode_base64($base64);
$decrypted = $cipher->decrypt($de_base64);
$c = $cipher->finish;

Ciphertext(b64): qz4eSQaFkQUkDOyJSbZf5W03HoldwtgvTLq0yJFRViKJnytf3PVSCGW2CYDjO+tRqV20oxeB2VPa 7NqN1TDSNQ==

there's a newline after the 2VPa section and another at the end

Ruby

require 'openssl'
require 'digest/sha2'
require 'base64'

message = "a really really long long text has differrent results???" 
cipher = OpenSSL::Cipher.new('aes-128-cbc')

# digest the key, iv and hmac_key so we have 16-byte length 
# also, it looks more of a funky password
# prepare cipher
cipher.encrypt
cipher.key = aes_key = "d2cb415e067c7b13"
cipher.iv = aes_iv = "e36dc751d0433f05"


encrypted = cipher.update(message)
encrypted << cipher.final()
b64_encoded = Base64.encode64(encrypted).encode('utf-8') #strict_encode64 guarantees no newlines, encode64 is default

puts "AES Key        : '#{aes_key}'"
puts "AES IV         : '#{aes_iv}'"
puts "Ciphertext(b64): '#{b64_encoded}'"

Ciphertext(b64): 'qz4eSQaFkQUkDOyJSbZf5W03HoldwtgvTLq0yJFRViKJnytf3PVSCGW2CYDj O+tRqV20oxeB2VPa7NqN1TDSNQ== '

Note the newlines chars after CYDj and after ==

I've seen the following: Perl & Ruby exchange AES encrypted information, but I'm not using padding=0

Community
  • 1
  • 1
Miguel Ping
  • 18,082
  • 23
  • 88
  • 136

2 Answers2

7

Newlines are not significant in Base64. You got exactly the same result from both languages.

While there should be absolutely no reason to do so, you could make the Perl version return the same string as the Ruby version as follows:

$base64 = encode_base64($encypted, '');
$base64 =~ s/\G.{60}\K/\n/sg;
ikegami
  • 367,544
  • 15
  • 269
  • 518
  • You are indeed correct. But if I use the following string `message@somelongstring;1234567890123123123` the results are different – Miguel Ping Oct 15 '12 at 17:49
  • 4
    Probably because you forgot to escape the `@` inside the string. That way Perl will see an array named `@somelongstring` inside the string and interpolate accordingly. You should REALLY `use strict;` and `use warnings;`; they would have caught this problem. – Moritz Bunkus Oct 15 '12 at 17:56
  • 3
    @Miguel Ping, Please don't ask new, completely unrelated questions in comments. – ikegami Oct 15 '12 at 17:58
  • I didn't know that the `@` sign was interpolated in perl. The comment was related; I didn't want to rewrite the question in order to keep your (good) original answer. Thanks! – Miguel Ping Oct 15 '12 at 18:00
  • 2
    One question was about base64. The other with properly building your string. Just goes to show you didn't even do the most basic of debugging if you thought they were the same question :( – ikegami Oct 15 '12 at 19:39
  • Please, dont assume things over the internet. This was in fact the first perl program I wrote. I wouldn't ask SO a question I could find out for myself. – Miguel Ping Oct 16 '12 at 09:11
  • 1
    @Miguel Ping, I didn't assume anything. You've demonstrated that you are able to print a string. – ikegami Oct 16 '12 at 14:23
3

The encode_base64 function takes a second parameter, called "eol" (end of line) which, by default, is '\n'.

The returned encoded string is broken into lines of no more than 76 characters each and it will end with $eol unless it is empty

Try:

$base64 = encode_base64($encypted, '');

instead.

the Tin Man
  • 158,662
  • 42
  • 215
  • 303
esskar
  • 10,638
  • 3
  • 36
  • 57