Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot
 
PerlMonks  

Encrypting Source Filter

by kschwab (Vicar)
on Dec 28, 2018 at 19:48 UTC ( #1227795=CUFP: print w/replies, xml ) Need Help??

After reading bliako's post, I was curious.

I wanted to experiment a bit with his "I want to be asked for a password/key at encryption stage and then asked just once" requirement. I didn't get it working with PAR, or any ability to also encrypt used modules, so it's not acceptable as an answer there. Might be useful to play with though. Works in a way that's similar to Acme::Bleach, other than I don't overwrite the original file. You'll need to have a working openssl binary in your PATH somewhere.

Feedback welcome.

Save this as "AESFilter.pm"...
package AESFilter; use IPC::Open2; our $openssl="openssl enc -aes-256-cbc -a"; our $marker = '#AESFilter'; sub encrypt { $_[0]=~s/$marker//gs; my $pid=open2(my $rdr,my $wrt,"$openssl 2>>/dev/null"); print $wrt $_[0]; close $wrt; my $output; while(<$rdr>) {$output.=$_}; close $rdr; waitpid($pid,0); my $status=$?>>8; if ($status !=0) { die("Exit status $status from openssl, encryption failed\n"); } return $output; } sub decrypt { my $pid=open2(my $rdr,my $wrt,"$openssl -d 2>>/dev/null"); print $wrt $_[0]."\n"; close $wrt; my $output; while(<$rdr>) {$output.=$_}; close $rdr; waitpid($pid,0); my $status=$?>>8; if ($status != 0) { die("Exit status $status from openssl, decryption failed\n"); } return $output; } open(IN,$0) or die "Can't open [$0]: $!\n"; my $prior=''; my $code=''; my $seen=0; while(<IN>) { if ($seen) { chomp; $code .= $_; next; } $prior .= $_; if (/use AESFilter;/) { $seen=1} } close IN; if ($code =~ s/^$marker//gm) { my $clear=decrypt($code); eval($prior.$clear); print STDERR $@ if $@; exit; } my $outfile=$0.".enc"; die "Encrypted file [$outfile] already exists\n" if (-e $outfile); my $encrypted=encrypt($code); open(OUT,">$outfile") or die "Can't open [$outfile] for write: $!\n"; printf OUT "%s%s\n%s",$prior,$marker,$encrypted; close OUT; exit; 1;

To play with it, create a script like what's below. The first time you run it, it will create an encrypted script, with an extension of ".enc". So, if your script is called "foo", it creates a new file called "foo.enc" that's encrypted. It's calling openssl to get a password, so you'll be prompted for a password.

#!/usr/bin/perl # so that you don't have to install AESFilter.pm, just # have it in your current dir use lib "."; # anything before the next line will be in the output in cleartext # ...anything after will be encrypted use AESFilter; print "test123\n"; print "again\n"; for ("one","two","three","four") { print $_."\n"; }
If you save the code in a file called "foo", and run it once (with a password of '0'), it will produce a file called "foo.enc", that looks like this:
#!/usr/bin/perl # so that you don't have to install AESFilter.pm, just # have it in your current dir use lib "."; # anything before the next line will be in the output in cleartext # anything after will be encrypted use AESFilter; #AESFilter U2FsdGVkX1/CjxWDKOh4Xdw/7c0PoKnkUFQsf5gxo3F7RXqcEtmdsAgeEmb1g/QO qd82hklpUxP/SNzbs34Z2NdzEStaDpeTlke1unf18gAw/2hlu78CIIItHVuAZlrH ovJhqCBhP0Rck1RwXt3cJw==
And, if you run that code, it will prompt for the password.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: CUFP [id://1227795]
Front-paged by davies
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others lurking in the Monastery: (1)
As of 2021-09-27 23:44 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found

    Notices?