In April 2006, I asked for the wisdom of the monks regarding encryption and file locking. Fast-forward to the present and I am begrudgingly being forced to implement the previously described problem. For a change, I am working with another programmer on this, though neither of us have any experience with encryption before tackling this project.

Code background story
The script takes form input, evaluates it based on a lot of factors, and then builds a fixed-length (1850 characters) line for each submission and writes that data into a flatfile, which is then passed off to another system for processing. Each flatfile can end up with anywhere from a few dozen to a few thousand lines per day.

Here's an example of how the code currently works (snipping out the long section of building many, many variables:

#!/usr/bin/perl use strict; use warnings; use CGI qw(:standard); use CGI::Carp qw(fatalsToBrowser); use Fcntl ":flock"; use POSIX; use File::CounterFile; use Crypt::Rijndael; use Crypt::CBC; require '../code_paths.conf'; [a lot of variable declarations go here] #SCRIPT setValues(); writeSubmissions(); exit; #SUBROUTINES sub setValues { [a lot of values are read in and set and worked with] #here's where we build the line # format for fixed-length line: my $filebegin_format = "%-1.1s%-8.8s%6.6d%-17.17s%-25.25s%-16.16s% +-1.1s%-9.9s%-9.9s%-8.8s%-35.35s%-25.25s%-2.2s%-12.12s%-3.3s"; #file l +ayout for characters 1-177 my $request_format = "%-4.4s%-4.4s%-1.1s%-1.1s%-151.151s"; #file l +ayout for requests 1-8 my $request9_format = "%-6.6s%-4.4s%-1.1s%-1.1s%-1.1s%-35.35s%-35. +35s%-35.35s%-25.25s%-2.2s%-12.12s%-3.3s%-4.4s"; #file layout for requ +est 9 my $fileend_format = "%-5.5d%-1.1s%-16.16s%-4.4s%-25.25s%-16.16s%- +9.9s%-1.1s%-40.40s%-14.14s%-2.2s%-9.9s%-3.3s%-3.3s%-10.10s%-40.40s%-2 +2.22s%-1.1s"; #file layout for characters 1630-1850 my $format = $filebegin_format . $request_format . $request_format + . $request_format . $request_format . $request_format . $request_for +mat . $request_format . $request_format . $request9_format . $fileend +_format; # build fixed-length line: $fl_line = sprintf $format, $filetype, $batch, $serial_number, $sy +s_time, $tt_lastname, $tt_firstname, $tt_mi, $ssn, $ssn_cor, $dob, $t +t_address, $tt_city, $tt_state, $tt_zip, $tt_country, $code_1, $date_ +1, $type_1, $priority_1, $filler, $code_2, $date_2, $type_2, $priorit +y_2, $filler, $code_3, $date_3, $type_3, $priority_3, $filler, $code_ +4, $date_4, $type_4, $priority_4, $filler, $code_5, $date_5, $type_5, + $priority_5, $filler, $code_6, $date_6, $type_6, $priority_6, $fille +r, $code_7, $date_7, $type_7, $priority_7, $filler, $code_8, $date_8, + $type_8, $priority_8, $filler, $code_9, $date_9, $type_9, $exception +_9, $priority_9, $addressee_9, $institution_9, $address_9, $city_9, $ +state_9, $zip_9, $country_9, $filler, $bill_total, $cc_type, $cc_numb +er, $cc_exp, $cc_name, $cur_lastname, $cur_firstname, $cur_mi, $cur_a +ddress, $cur_city, $cur_state, $cur_zip9, $cur_pcode, $cur_country, $ +phone, $email, $filler, $reject; $asr_line = uc($fl_line); #uppercase $asr_line =~ tr/\000-\037/ /; # removing control characters, be +st option for speed } #subroutine to keep writing the plain file sub writeSubmissions{ if ($filetype == 1 ) { $log_file = "pem.txt"; } else { $log_file = "act.txt"; } open LO, ">>$log_file"; flock LO, LOCK_EX; print LO "$asr_line\n"; close LO; }

Adding encryption
After many conversations about security and encryption, we decided we would encrypt each line before it gets written into the file, so the submitted data would never be anywhere but memory unencrypted. Then, after the file was passed onto another server in a different secure system, that system would deal with opening the file, decrypting each line, writing the decrypted data into a file for processing (don't ask why, its complicated).

We're attempting to do both the encrypting and decrypting on the same server during development since obviously we need to be able to decrypt the file to confirm we are getting the encryption correct.

The current attempt is to replace the writeSubmissions() subroutine with this code:

sub writeSubmissions{ if ($filetype == 1 ) { $log_file = "pem.enc"; } else { $log_file = "act_encrypted.enc"; } $my_key = `openssl enc -bf-cbc -d -in key_file.txt -k encrypt`; $cipher = Crypt::CBC->new( {'key' => $my_key, 'cipher' => 'Rijndael', 'regenerate_key' => 1, 'padding' => 'standard', }); open FH_crypted, ">>$log_file"; #binmode FH_crypted; flock FH_crypted, LOCK_EX; $cipher->start('encrypting'); print FH_crypted $cipher->crypt($asr_line); print FH_crypted $cipher->finish; close FH_crypted; }
and use this script to decrypt a command line-specified file
#!/usr/bin/perl use strict; use warnings; use Crypt::Rijndael; use Crypt::CBC; #-------------------------------------------------------------------- # Parameters #-------------------------------------------------------------------- my $my_key; my $plain_text; my $encrypted = $ARGV[0]; my $cipher; my $buffer; my $decrypted = $encrypted; $decrypted =~ s/\.enc/\.txt/; $my_key = `openssl enc -bf-cbc -d -in key_file.txt -k encrypt`; $cipher = Crypt::CBC->new( {'key' => $my_key, 'cipher' => 'Rijndael', 'regenerate_key' => 1, 'padding' => 'standard', }); #-------------------------------------------------------------------- # Decryption #-------------------------------------------------------------------- open(FH_encrypted, "<$encrypted"); open(FH_decrypted, ">$decrypted"); $cipher->start('decrypting'); while (read(FH_encrypted,$buffer,1851)) { print FH_decrypted $cipher->crypt($buffer); } print FH_decrypted $cipher->finish; close FH_encrypted; close FH_decrypted;

Which isn't working. I'm writing the line both into an encrypted and a plain text version while testing (for comparisons) and the plain/original version file is 1851 bytes while the encrypted version is 1872 bytes (which I assume is padding for the blocksize stuff that I don't really get). When we run the decrypt script the file is then 1856 bytes (and is still unreadable garbly-gook, but different garbly-gook than the original encrypted file.)

I realize there are many factors in dealing with encryption, so I'm looking to see if there is something inherently flawed in the logic of our current plan. One other thing to note that I'm trying to figure out is that the html page with the form and the cgi script it calls, as well as the decrypt script are all owned by a user "webmaster" but the file that the script writes is owned by "apache". Could this be a source of the problem? I'm trying to figure it out but I don't have the permissions on this server to change users or ownership and I'm trying to figure out what to communicate to my unix admin that should (if anything) be changed.

Thanks!


I learn more and more about less and less until eventually I know everything about nothing.

In reply to line by line Encryption fun with Crypt::CBC and Rijndael? File Ownership issues? by hmbscully

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.