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

I am running up against a wall and hitting it hard. I am needing to encrypt fields and not he entire file for data upload. I then need to use that encrypted field as a key in a system and then when extracted, I need to be able to decypt it. Below are sample lines from a fake text creator to illustrate my quandary."

customerid registered_date first_name last_name address city state zip age primary_email
689-08-2317 1518973472 Sascha Urian 85 Sunbrook Road San Antonio Texas 78250 55 surian0@archive.org
201-25-0510 1515436776 Gilbertine Impy 3136 Thierer Trail Mc Keesport Pennsylvania 15134 49 gimpy1@edublogs.org
616-54-5114 1518645090 Christabella Gunther 4 Autumn Leaf Junction Chicago Illinois 60619 26 cgunther2@nature.com

I would need to read in the file, encrypt column 1 & 9, then output the file in the same format but with those values having encrypted values. I may be going down the wrong path here and really need a hash process but I have exhausted my working brain cells at this point and need some help. The end format would look like this below.

customerid registered_date first_name last_name address city state zip age primary_email
$#diDse*eES 1518973472 Sascha Urian 85 Sunbrook Road San Antonio Texas 78250 55 weSIDUsae34@#$%%#@@
eSDE#24DSET 1515436776 Gilbertine Impy 3136 Thierer Trail Mc Keesport Pennsylvania 15134 49 sdies#@SERUSEeset
OEDUse#@#$2 1518645090 Christabella Gunther 4 Autumn Leaf Junction Chicago Illinois 60619 26 mvxosef@#w32553S

I have been trying to modify this base code

#!/usr/bin/perl use strict; use Crypt::CBC; #unless (scalar @ARGV == 3) { # #die "Usage: $0 encrypt|decrypt|en|de \$mysecretkey \$file_to_den +crypt"; #} #my $type = shift @ARGV; #my $key = shift @ARGV; #my $file = shift @ARGV; my $type = "de"; my $key = "12345"; my $file = "C:\\perlinputfiletest\\fakedata.txt.encrypt"; die "The first ARGV should be one of de, en, encrypt, decrypt" if ($ty +pe !~ /^(en|de)(crypt)?$/); die "the file $file is not existence" unless (-f $file); my $DEBUG = 1; print "type is $type, key is $key, file is $file\n" if $DEBUG; my $cipher = Crypt::CBC->new( -key => $key, -cipher => 'Blowfish' ); local $/; open(FH, $file) or die $!; flock(FH, 2); my $data = <FH>; close(FH); my ($save_data, $save_file); if ($type =~ /^en(crypt)?$/) { $save_data = $cipher->encrypt($data); $save_file = $file . '.encrypt'; } else { $save_data = $cipher->decrypt($data); $save_file = $file . '.decrypt'; } open(FH, '>', $save_file) or die $!; print FH $save_data; close(FH); if (-e $save_file) { print "$type file $file to $save_file OK\n"; } else { print "failed without reason\n"; }

Replies are listed 'Best First'.
Re: Using Cypher::CBC to encrypt fields in a file - Need Monk Help
by talexb (Chancellor) on Feb 21, 2019 at 19:17 UTC
      I would need to read in the file, encrypt column 1 & 9, then output the file in the same format but with those values having encrypted values.

    OK, so it looks like you have some of the framework done. Looking at the Crypt::CBC page on MetaCPAN, you're not encrypting the fields correctly. You need to get each line of the file, split it into fields, encrypt two of the fields, and write the fields out to a new file.

    use autodie; # Using this module means open and close errors are # handled nicely. my @affected_fields = qw/0 8/; .. # Figure out the input and the output file names here .. .. open ( my $input_fh, '<', $input_file ); open ( my $output_fh, '>', $output_file ); while ( <$input_file> ) { my @fields = split ( /,/ ); if ( $type =~ /^en(crypt)?$/ ) { foreach ( @affected_fields ) { $fields[ $_ ] = $cipher->encrypt( $fields[ $_ ] ); } } else { # I would prefer to use an elsif here, but # you could catch this during parameter checking. foreach ( @affected_fields ) { $fields[ $_ ] = $cipher->decrypt( $fields[ $_ ] ); } } print $output_fh join (',', @fields ) . "\n"; } close ( $input_fh ); close ( $output_fh );
    PS, Always, always, ALWAYS use strict and use warnings.

    Alex / talexb / Toronto

    Thanks PJ. We owe you so much. Groklaw -- RIP -- 2003 to 2013.

Re: Using Cypher::CBC to encrypt fields in a file - Need Monk Help
by bliako (Abbot) on Feb 21, 2019 at 19:50 UTC

    And this shows how to abstract reading [CST]SV files and keep sane:

    #!/usr/bin/perl use strict; use warnings; use Crypt::CBC; use Text::CSV; use Data::Dumper; my $type = "en"; my $key = "12345"; my $file = "data.txt.encrypt"; my $DEBUG = 1; print "type is $type, key is $key, file is $file\n" if $DEBUG; my $cipher = Crypt::CBC->new( -key => $key, -cipher => 'Blowfish' ); my $data = Text::CSV::csv( in => $file, sep_char => ' ', headers => 'auto', keep_headers => \my @headers ); if( ! $data ){ print STDERR "$0 : call to Text::CSV::csv() has failed +for input file '$file'.\n"; exit(1) } print Dumper($data) if $DEBUG; my ($outfile, $cipher_coderef); if( $type =~ /^en(crypt)?$/ ){ $cipher_coderef = sub { return $cipher->encrypt($_[0]) }; ($outfile = $file) =~ s/encrypt/decrypt/; } else { $cipher_coderef = sub { return $cipher->decrypt($_[0]) }; ($outfile = $file) =~ s/decrypt/encrypt/; } my @columns_to_encrypt = ('customerid', 'age'); my $rid = 0; foreach my $row (@$data){ $rid++; foreach my $colname (@columns_to_encrypt){ print "$0 : row $rid, column '$colname' : processing ...\n"; $row->{$colname} = $cipher_coderef->($row->{$colname}); } } if( ! Text::CSV_XS::csv( in => $data, sep_char => ' ', headers => \@headers, out => $outfile ) ){ print STDERR "$0 : call to Text::CSV_XS::csv() has failed.\n"; ex +it(1) } print "$0 : success, output in '$outfile'.\n";

      Very nicely done .. you caught my mistake about assuming that it was a CSV file, when in fact it was space delimited. You also set up a coderef for the encryption/decryption step, which is something that occurred to me, but decided against in order to get an example solution done quickly. And Text::CSV is a great module.

      Alex / talexb / Toronto

      Thanks PJ. We owe you so much. Groklaw -- RIP -- 2003 to 2013.

        quite proud of my coderefs actually, thanks talexb