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

Hi, I have received a part of JAVA code wich I need to convert to Perl. This is a part of an encryption sequence on a JAVA based system.
iMode = 0; String key = "1234567890"; byte[] bytes = new byte[256]; byte[] kbytes = key.getBytes(); for (int i = 0; i < bytes.length; i++) { if (i < kbytes.length) { bytes[i] = kbytes[i]; } else { bytes[i] = (byte) i; } } byte[] md5digest = md5DigestAsBytes(bytes); try { theGeneratedKey = Twofish_Algorithm.makeKey(md5digest); blockSize = Twofish_Algorithm.blockSize();
There is no issue in the Twofish part. My issue is the byte arrays that are being called. I need to rewrite them to perl, but I am stuck at this part:
byte[] bytes = new byte[256];
how do you create a new 256 byte array in perl. The objective, to decrypt and encrypt data between Java and Perl.

Replies are listed 'Best First'.
Re: Java to perl conversion
by BrowserUk (Patriarch) on May 31, 2013 at 09:59 UTC

    Digest::MD5 doesn't take an array; it takes a string.

    If simply passing your strings to Digest::MD5::md5() does not produce the same 16-byte value that the Java code is producing, it will be because the Java code is digesting the entire 256-byte packet including the trailing nulls.

    Therefore the solution is to pad the string to 256-bytes with nulls before generating the md5:

    my $string = ...; # get the string from wherever $string = pack 'a256', $string; ## Will null pad to the specified leng +th my $md5 = md5( $string ); ... do the twofish stuff.

    That doesn't deal with strings that start out greater than 256, but neither does the Java code.

    It will also not correctly deal with strings where char != byte.

    If that is a requirement, the simplest solution will be to turn off the utf flag before the pack, but there is undoubtedly a (suite of) modules that will do the same thing.


    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
Re: Java to perl conversion
by RichardK (Parson) on May 31, 2013 at 10:04 UTC

    Have a look at Digest::MD5 and you'll see that it has an add method and you won't have to bother with byte arrays.

    So,I think you should be able to do something like this, untested code

    my $md5 = Digest::MD5->new; $md5->add($key); $md5->add( chr($_) ) for length($key) .. 255; my $tfkey = $md5->digest();

    If that doesn't work then you'll have to play around with pack/unpack.

Re: Java to perl conversion
by Anonymous Monk on May 31, 2013 at 09:10 UTC
      The Crypt::Twofish is not the issue. the issue is to generate the exact same md5 digest. That one is build up from the bytes of the string
      java: String key = "1234567890"; perl: my $key = "1234567890";
      so I need to be able to create the exact same 256 byte array.
      java: byte[] bytes = new byte[256];
      getting the bytes of the string is also an issue
      java: byte[] kbytes = key.getBytes();
      the loop in the code is also quite simple.
      So what I really need: perl code to
      1. Generate a 256 byte array 2. perl code to convert the characters from stringdata to byte. Thanks

        Most likely, you will want to use either an array, and put the string there (split), or just use a string and substr to access the characters within the string.

        Arrays and strings are not sized in Perl.

        ... 1. Generate a 256 byte array 2. perl code to convert the characters from stringdata to byte. Thanks

        Um, you don't need to turn a string into an array to generate an md5sum, see Digest::MD5

        You also don't need an array for Crypt::Twofish

        perlintro explains about perl variable types, perldata explains further, then binmode and perlunitut

Re: Java to perl conversion
by MaGiCaLB (Initiate) on May 31, 2013 at 10:22 UTC
    To clarify a bit more of the situation

    The encryption cipher from JAVA is out of my hands and generated by an API
    I somehow need to match the same cipher in perl

    JAVA CODE to generate the Cipher
    String key = "just a bunch of text"; byte[] bytes = new byte[256]; byte[] kbytes = key.getBytes(); for (int i = 0; i < bytes.length; i++) { if (i < kbytes.length) { bytes[i] = kbytes[i]; } else { bytes[i] = (byte) i; } } byte[] md5digest = md5DigestAsBytes(bytes); try { theGeneratedKey = Twofish_Algorithm.makeKey(md5digest); blockSize = Twofish_Algorithm.blockSize(); catch (java.security.InvalidKeyException ike) { throw new Exception(Exception.E_SECURITY, "Invalid security key ' +" + new String(md5digest) + "'", ike); }
    the part that i need a bit help with:
    String key = "just a bunch of text"; byte[] bytes = new byte[256]; byte[] kbytes = key.getBytes(); for (int i = 0; i < bytes.length; i++) { if (i < kbytes.length) { bytes[i] = kbytes[i]; } else { bytes[i] = (byte) i; } } byte[] md5digest = md5DigestAsBytes(bytes);
    The rest is quite obvious
    I am lacking the experience with java to replicate the code and test it against a perl version
    Question should read:
    I need to match the exact same cipher in Perl
    to be able to utilize Crypt::Twofish and decrypt the data. How can I do this in Perl

    This is my first post here.
      the part that i need a bit help with:

      Looking again, I'm wrong! The string/array isn't null padded, but rather padded with bytes equivalent to their position.

      This does exactly that.

      But you will need to understand that Java's byte arrays and Perl's scalars (when they contain strings) are effectively equivalent.

      So, use:

      my $string = "just a bunch of text"; $string .= pack 'C*', length( $string ) .. 255; my $md5 = md5( $string );

      With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.