in reply to Re^9: line by line Encryption fun with Crypt::CBC and Rijndael? File Ownership issues? (code)
in thread line by line Encryption fun with Crypt::CBC and Rijndael? File Ownership issues?

Thank you for your help.

First, could you confirm that you really need to ability to append record to an existing encrypted file? If I understand the question correctly; not always, but maybe at times and therefore I have to code that in.

I still cannot get it to decrypt the file that is encrypted using BlowfishNET 2.1.2. Here is the code that includes your most recent updates as well. Pardon the long variable names.

sub encryptData { my ( $cObject ) = @_; my $buffer; open(PLAINTEXT, "<", $plaintextReadFileName) || die("Cannot open f +ile $plaintextReadFileName"); binmode PLAINTEXT; flock PLAINTEXT, LOCK_SH; open(my $fhENCRYPTEDFILE, ">", $encryptedFileName) || die("Cannot +open file $encryptedFileName"); binmode $fhENCRYPTEDFILE; flock $fhENCRYPTEDFILE, LOCK_EX; while (read(PLAINTEXT,$buffer,4)) { utf8::encode($buffer) if ($type eq "utf8base64"); $buffer = $cObject->encrypt($buffer); print $fhENCRYPTEDFILE (pack('N', length($buffer)), $buffer); } close PLAINTEXT; close $fhENCRYPTEDFILE; print "Encrypted $plaintextReadFileName to $encryptedFileName."; } sub encodeData { open(my $fhENCRYPTEDFILE, "<", $encryptedFileName) || die("Cannot +open file $encryptedFileName"); binmode $fhENCRYPTEDFILE; flock $fhENCRYPTEDFILE, LOCK_EX; open(my $fhENCODEDnENCRYPTEDFILE, ">", $encodedFileName) || die("C +annot open file $encodedFileName"); binmode $fhENCODEDnENCRYPTEDFILE; flock $fhENCODEDnENCRYPTEDFILE, LOCK_EX; if ($type eq "utf8base64") { $utf8base64EncryptedFile = do { local( $/ ) ; <$fhENCRYPTEDFIL +E> } ; print $fhENCODEDnENCRYPTEDFILE encode_base64($utf8base64Encryp +tedFile); } close $fhENCRYPTEDFILE; close $fhENCODEDnENCRYPTEDFILE; print "Encoded $encryptedFileName to $encodedFileName."; } sub decodeData { open(my $fhENCODEDFILE, "<", $encodedFileName) || die("Cannot open + file $encodedFileName"); binmode $fhENCODEDFILE; flock $fhENCODEDFILE, LOCK_EX; open(my $fhDECODEDFILE, ">", $decodedFileName) || die("Cannot open + file $decodedFileName"); binmode $fhDECODEDFILE; flock $fhDECODEDFILE, LOCK_EX; $utf8base64EncodedFile = do { local( $/ ) ; <$fhENCODEDFILE> } ; print $fhDECODEDFILE decode_base64($utf8base64EncodedFile); close $fhENCODEDFILE; close $fhDECODEDFILE; print "Decoded $encodedFileName to $decodedFileName."; } sub decryptData { my $cObject = shift; my ( $length, $buffer ); open( my $fhREADFROM, "<", $decodedFileName ) || die("Cannot open +encrypted file $decodedFileName"); binmode $fhREADFROM; flock $fhREADFROM, LOCK_SH; open( finalFile, ">", $decryptedFileName ) || die("Cannot open fil +e $decryptedFileName to write decrypted contents"); binmode finalFile; flock finalFile, LOCK_EX; while (!eof($fhREADFROM)) { $length = unpack('N', read_bytes($fhREADFROM, 4)); $buffer = read_bytes($fhREADFROM, $length); utf8::decode( my $str = $cObject->decrypt( $buffer ) ); print finalFile $str; } close $fhREADFROM; close finalFile; print "Decrypted $decodedFileName to $decryptedFileName."; } sub read_bytes { my ($fh, $to_read) = @_; my $buf = ''; while ($to_read) { my $bytes_read = read($fh, $buf, $to_read, length($buf)); die("$!\n") if !defined($bytes_read); die("Unexpected end of file\n") if !$bytes_read; $to_read -= $bytes_read; } return $buf; } encryptData($cObject); encodeData() if ($type eq "utf8base64"); decodeData() if ($type eq "utf8base64"); decryptData($cObject);

Just to clarify; the encrypt, encode, decode and decrypt functions do work if I do all the encryption, encoding, decoding and decryption on my end. However, I can't get it to decrypt the file that is encrypted using the BlowfishNET 2.1.2 library from http://www.hotpixel.net/software.html using the BlowfishSimple class. I'll paste the README here again:

"For efficiency the given string will be UTF-8 encoded and padded to the next 8byte block border. The CBC IV plus the encrypted data will then be BASE64 encoded and returned as the final encryption result."

I am confused and hope you can clarify.

I assume encryption is performed in the following order based upon what the README for the BlowfishNET 2.1.2 library says:

Now, while decrypting, I was trying to go in the following order:

What am I missing here? Am I not using unpack correctly for my purpose? Could you please help me understand the following line: $length = unpack('N', read_bytes($fhREADFROM, 4)); What would the value of $buf be in the call to read_bytes here? Thanks again for your help.

  • Comment on Re^10: line by line Encryption fun with Crypt::CBC and Rijndael? File Ownership issues? (code)
  • Select or Download Code

Replies are listed 'Best First'.
Decrypting BlowfishNET (was Re^11: line by line Encryption ...)
by ikegami (Patriarch) on Aug 01, 2008 at 20:48 UTC

    First, could you confirm that you really need to ability to append record to an existing encrypted file?

    If I understand the question correctly; not always, but maybe at times and therefore I have to code that in.

    Sounds like you don't need the code from this thread at all, and I'm curious as to why you posted in this thread at all. Your problem has nothing to do with the OP's.

    (If you ever do need to append to a file, just decrypt it, append, and encrypt the new contents.)

    Even if you will be using this for log files where the append code would be useful, you should be concentrating on being able to decrypt the code from BlowfishNET. One problem at a time.

    However, I can't get it to decrypt the file that is encrypted using the BlowfishNET 2.1.2

    I don't feel like installing this, so I'll need the following:

    • A runnable program that consists of your attempt at decrypting BlowfishNET files (and nothing else).
    • A message encrypted using BlowfishNET.
    • The key with which the message was encrypted.
      Sounds like you don't need the code from this thread at all, and I'm curious as to why you posted in this thread at all.

      This thread serves our purpose. I started working on this with the intention to write something to both encrypt and decrypt the data. I chose to encrypt processed data and then write into the file. In reality we never have a plain-text file, I put that in the code here only for the purpose of testing. Instead, we have one processed data record from a webform submission (I skipped those details since the primary thread seemed to have a similar scenario, sans the webform maybe.). So the idea was to get each data record, encrypt it and then write into the file. The thought behind choosing this methodology was that the webform is actually hosted on another system (not part of our group) and this allowed to have plaintext data to be nowhere but in memory on the other system.

      The purpose of the decryption section was that the encrypted file would be read in, decrypted and written into another black-box system (owned and operated by another group) that would store into their own proprietary database as they decrypt using our decryption section. In the example above, it's being stored into a file here to try to get it working first.

      Now, the people encrypting the file can't use PERL and therefore all this goes out of the window. So far, they want to use just the BlowfishNET 2.1.2 library and class mentioned above. So, I am no longer concerned with the encryption part, only with decrypting it. However, I am confused as to how encryption is being performed using that class and therefore I queried you about the order to see if you think my understanding of the order of encryption is correct. We have been guided to the README docs and basically asked to figure it out from there. I hope I am explaining the situation correctly here, but I am not sure if they encrypt by making a call to the BlowfishSimple class everytime they process a record (one webform submission) or is it basically being called to encrypt a plaintext file as a whole. I am lost and therefore the post.

      I'll put in a request for an encrypted message using BlowfishNET that I can post here and then put it here along with the key.

      Thank you for your help.

        Here is a message encrypted using BlowfishNET. The key used for encryption is "Abcdefghijklmnopqrstuvwxyz1234567890".
        IV is not specified when the call is made to BlowfishNET. I store the encrypted message in a file called "BFSTest_encoded.csv".

        mGWcw1XJV3ooXbGvzBuShOA2gwcUnW11NZnHm1Nm 8JQktRSoaAKl369jL8ZLnJNF71I5ctZq8wGGtfov iLj6PoXZWlzcasgBBUMefjGa0h+L53/VODmqCDaL 6jnZycB5VTngY5gt/9VpYxVW0KB5yR0TJrhHQa02 Vgn1I9ePtmbJfOkALXZPwY0H8MDULkzIYX409iSm 6zgu76UvW81qpJiakFDi9jmIbL4NVWYRlVR1xLRC HiM8X8q0yCT1ZQO9HJE8vHc/jKdEOi8QGNyAOtdd ku7Ikg4Pzwpk7g+R/TOCx7Q8xDKbV93sFHu1s3co pZrpCcNmd8Oy1CFazZ5FweWwsFqfgxMqopMrtaG6 Qc1J7cB3fYpI2RDN6xbAJ8HPZWGdOQsobopv+Czt GFuzVaVfwz8YXrLEXlbRFfv8Cpt8Q320NAAhwjFj eEUMyPCpzVZaBske4NDJ++7JomijlS8H8cHmmD6P Hbopy41W8BF9tsV9nqXgYeiVna98MNTEkyToyP/Z kBhGYJcutv3s9pG7SydwuKCxCd+Dugusnu8lM10/ 5UmGJ7YTGFCJvtfpXR9XoMCQ++eT4/YN9kZlim+2 bkjh01xPnG9r7PChWAVxpUVjOisGlZKrPV6tQRPU qwQ0die7XienUt5e+jACACGMqXWA4O8P5sg/iT3w Z2+dDIQiUnxCIATKn74/B8V9PDdtHnr5XOP5KPKK aYcz/gXt1Q6WkWawUIoLvCkobkm5o7MXeAiJCtet emfA86bV

        When decrypted correctly it should look like this:

        blowfishsimple,3030,encrypt,this,then,decrypt,1232,it0
        blowfishsimple,3030,encrypt,this,then,decrypt,1232,it1
        blowfishsimple,3030,encrypt,this,then,decrypt,1232,it2
        blowfishsimple,3030,encrypt,this,then,decrypt,1232,it3
        blowfishsimple,3030,encrypt,this,then,decrypt,1232,it4
        blowfishsimple,3030,encrypt,this,then,decrypt,1232,it5
        blowfishsimple,3030,encrypt,this,then,decrypt,1232,it6
        blowfishsimple,3030,encrypt,this,then,decrypt,1232,it7
        blowfishsimple,3030,encrypt,this,then,decrypt,1232,it8
        blowfishsimple,3030,encrypt,this,then,decrypt,1232,it9

        Below is the runnable program with which I am unsuccessfully trying to decrypt the encrypted message above.
        #!/usr/bin/perl -w use strict; use warnings; use Crypt::CBC; use Fcntl ':flock'; use MIME::Base64; my $encodedFileName = "BFSTest_encoded.csv"; my $decodedFileName = "BFSTest_decoded.csv"; my $decryptedFileName = "BFSTest_decrypted.csv"; my $cCipher = "Blowfish"; my $cKey = q{Abcdefghijklmnopqrstuvwxyz1234567890}; my $cIV = "randomiv"; my $cObject = Crypt::CBC->new({ key => $cKey, cipher => $cCipher }); croak( "Invalid cipher type for encryption" ) unless $cObject; sub read_bytes { my ($fh, $to_read) = @_; my $buf = ''; while ($to_read) { my $bytes_read = read($fh, $buf, $to_read, length($buf)); die("$!\n") if !defined($bytes_read); die("Unexpected end of file\n") if !$bytes_read; $to_read -= $bytes_read; } return $buf; } sub decryptNETData { my ( $length, $buffer ); print "Now DECRYPTING $decodedFileName for current client ... \n"; open( my $fhREADFROM, "<", $decodedFileName ) || die("Cannot open +encrypted file $decodedFileName"); binmode $fhREADFROM; flock $fhREADFROM, LOCK_SH; open( finalFile, ">", $decryptedFileName ) || die("Cannot open fil +e $decryptedFileName to write decrypted contents"); binmode finalFile; flock finalFile, LOCK_EX; # Tried to slurp, decrypt and decode here, but that did not work e +ither. my $decodedFile = do { local( $/ ) ; <$fhREADFROM> } ; utf8::decode( my $str = $cObject->decrypt( $decodedFile ) ); print finalFile $str; #while (!eof($fhREADFROM)) { # $length = unpack('N', read_bytes($fhREADFROM, 4)); # $buffer = read_bytes($fhREADFROM, $length); # print finalFile $cObject->decrypt( $buffer ); #} close $fhREADFROM; close finalFile; print "Decrypted $decodedFileName to $decryptedFileName. \n"; } sub decodeData { open(my $fhENCODEDFILE, "<", $encodedFileName) || die("Cannot open + file $encodedFileName"); binmode $fhENCODEDFILE; flock $fhENCODEDFILE, LOCK_EX; open(my $fhDECODEDFILE, ">", $decodedFileName) || die("Cannot open + file $decodedFileName"); binmode $fhDECODEDFILE; flock $fhDECODEDFILE, LOCK_EX; my $utf8base64EncodedFile = do { local( $/ ) ; <$fhENCODEDFILE> } +; #utf8::decode( my $str = decode_base64($utf8base64EncodedFile) ); print $fhDECODEDFILE decode_base64($utf8base64EncodedFile); close $fhENCODEDFILE; close $fhDECODEDFILE; print "Decoded $encodedFileName to $decodedFileName. \n"; } decodeData(); decryptNETData();

        Also, I am copying below the encrypt subroutine from the BlowfishSimple class. I apologize if this is of no use. I don't understand how it is padding the data. I assume encryption is performed in the following order:

        • UTF-8 encoded
        • Padded to next 8-byte block border (I am unsure about this) and Encrypted
        • BASE64 encoded

        We have taken your input and are encrypting the entire file as once. Therefore, the input to the BlowfishSimple class would be the entire file that needs to be encrypted.
        public String Encrypt(String plainText) { int i, origLen, len, mod; byte[] ueData, inBuf, outBuf, iv; ueData = Encoding.UTF8.GetBytes(plainText); origLen = ueData.Length; len = origLen; mod = len % BlowfishCBC.BLOCK_SIZE; len = (len - mod) + BlowfishCBC.BLOCK_SIZE; inBuf = new byte[len]; Array.Copy(ueData, 0, inBuf, 0, origLen); i = len - (BlowfishCBC.BLOCK_SIZE - mod); while (i < len) { inBuf[i++] = (byte)mod; } outBuf = new byte[inBuf.Length + BlowfishCBC.BLOCK_SIZE]; iv = new byte[BlowfishCBC.BLOCK_SIZE]; this.rng.GetBytes(iv); this.bfc.IV = iv; this.bfc.Encrypt( inBuf, 0, outBuf, BlowfishCBC.BLOCK_SIZE, inBuf.Length); Array.Copy(iv, 0, outBuf, 0, BlowfishCBC.BLOCK_SIZE); String sResult = Convert.ToBase64String(outBuf); Array.Clear(inBuf, 0, inBuf.Length); return sResult; }

        Thank you for your help.