LINUX GAZETTE

[ Prev ][ Table of Contents ][ Front Page ][ Talkback ][ FAQ ][ Next ]

"Linux Gazette...making Linux just a little more fun!"


Encrypting Data in Web Forms

By Mark Nielsen


  1. References
  2. Introduction
  3. Using Blowfish
  4. Converting Encrypted key to Hex.
  5. Encrypt and Decrypted Methods
  6. Why do this stuff?
  7. Conclusion

References

  1. http://www.perl.com/CPAN-local/modules/by-category/14_Security_and_Encryption/Crypt/Crypt-Blowfish-2.06.readme
  2. http://www.perl.com/pub/doc/manual/html/pod/perlfunc/pack.html

Introduction

There may be times when you want to send encrypted data to a user on your web server. For example, if you want to hide the numeric id of an account. However, there is a problem sending encrypted data, it is binary. Also, there aren't too many packages that are easy to encrypt data in Perl.

Using Blowfish

Blowfish is the easiest encryption module to use in Perl. It doesn't have any licensing restrictions either. I believe some other modules also recently lost their resctrictions, but I always go with the ethically pure software if it is just as good as the other unethical software.

Here is an easy way to encrypt and then decrypt the data. Note, I don't print the binary encrypted string because it won't be printable.

use Crypt::Blowfish;

my $Blowfish_Key = "An extremely dumb password you should change.";
my $Blowfish_Cipher = new Crypt::Blowfish $Blowfish_Key;

  ### Remember, sentence has to be 8 long
my $Sentence = "DumbWord";
my $Encrypted = $Blowfish_Cipher->encrypt($Sentence);
my $Decrypted = $Blowfish_Cipher->decrypt($Encrypted);

print "Do the next two lines match?\n";
print "$Sentence\n";
print "$Decrypted\n";

Converting Encrypted key to Hex

"pack" and "unpack" can be a little confusing to use in perl. Basically, they convert data into different formats. Like converting characters into their numeric ASCII equiv or converting hex numbers to integers, etc.

All we want to do is convert binary data to hex data. Why is hex data important? It is alphanumeric and won't screw up a browser with weird characters. There is no security using hex, but it is compact, and it is always a fixed length. It converts each character into a 2 hex characters (or numbers). Always having an exact length per character makes it easy to convert back to binary data.

Here is a simple command to convert a sentence to hex, and then converting it back to text.

my $Sentence = "This is a dumb sentence.\n";
print "$Sentence\n";
my $Hex = unpack("H*",$Sentence);
print "$Hex\n";
my $Sentence2 = pack("H*",$Hex);
print "$Sentence2\n";

Encrypt and Decrypted Methods for cgi webpages

Here is a older smaller version of what we use at gnujobs.com, and it doesn't have a "new" method. This is just a simple package. Here is how you can call the methods:

First, I assume you are using mod_perl. In your root directory for the apache webserver, create this directory,

mkdir -p lib/perl/MyPackage
Then copy the module below to the location lib/perl/MyPackage/Misc.pm.

To encrypt data,

use MyPackage::Misc;
my $Data = "Just a dumb sentence I want to encrypt";
my $Encrypted = MyPackage::Misc->Encrypt($Data);

To decrypt info,
use MyPackage::Misc;
my $Decrypted = MyPackage::Misc->Decrypt($Encrypted);

And here are the methods. You should really customize these modules for your needs. I kept $Blowfish_Cipher as a global variable for the package so that it only needs to get compiled once. I guess I might as well copyright it with the GPL just to promote GPL. Here is the GNU GPL license. (text version of this listing)

#!/usr/bin/perl

# Copyright (C) 2000 Mark E. Nielsen at GNUJobs.com

# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

# Web-Encrypt-Example version 0, Copyright (C) 2000 Mark E. Nielsen at GNUJobs.com
# Web-Encrypt-Example comes with ABSOLUTELY NO WARRANTY.
# This is free software, and you are welcome
# to redistribute it under certain conditions.

# The Computer Underground, Inc., hereby disclaims all copyright
# interest in the program `Web-Encrypt-Example'
# written by Mark E. Nielsen.
# Mark E. Nielsen, President of The Computer Underground

package MyPackage::Misc;

use strict;
use Crypt::Blowfish;

my $Blowfish_Key = "An extremely dumb password you should change.";
my $Blowfish_Cipher = new Crypt::Blowfish $Blowfish_Key;

#-----------------------------------
sub Encrypt
{
my $self = shift;
my $String = shift;

my $Temp = $String;
my $Encrypted = "";
while (length $Temp > 0)  
  {
    ### If less than 8 characters, padd it with tabs
  while (length $Temp < 8) {$Temp .= "\t";}
    ### Ecnrypt the 8 length segment
  my $Temp2 = $Blowfish_Cipher->encrypt(substr($Temp,0,8));
    ### Add it to the end
  $Encrypted .= $Temp2; 
    ### If it is 8 or less, abort, otherwise get the next segment
  if (length $Temp > 8) {$Temp = substr($Temp,8);} else {$Temp = "";}
  }

my $Unpacked = unpack("H*",$Encrypted);

return ($Unpacked);
}

#--------------------------------
sub Decrypt
{
my $self = shift;
my $String = shift;

my $Packed = pack("H*",$String);

my $Temp = $Packed;
my $Decrypted = "";
while (length $Temp > 0)  
  {
  my $Temp2 = substr($Temp,0,8);
    ### In theory, we could up with less than 8 characters, check
  if (length $Temp2 == 8) 
    {
    my $Temp3 = $Blowfish_Cipher->decrypt($Temp2);
    $Decrypted .= $Temp3;
    } 
  if (length $Temp > 8) {$Temp = substr($Temp,8);} else {$Temp = "";}
  }
   ### Getting rid of tabs at the end, which could be a bad thing
   ### but is how I did it. 
$Decrypted =~ s/\t+$//g;

return ($Decrypted);
}

NOTE: There is one special thing you ought to do when decrypting information. Check to see if it contains valid data. If it is numeric, make sure it is a number.Usually a smart idea is to always assume the number is positive and less than a billion, and do something like this,

my $Error = 1;
if (($Value >0) && ($Value < 1000000000)) {$Error = 0;}
if ($Error == 1) {print "Darn it, this sucks, no valid data, bye bye!"; exit;}

Why do this stuff?

The need to encrypt data so that people can't put in arbitrary values can be very useful sometimes. Granted, a web server shouldn't ever be setup to let people put in arbitrary values, but sometimes if you are not careful, people can download all information out of your database by simply changing unique identifiers in a web form. Most people don't care, but some do.

Also, if correctly setup, the encrypted data won't interfere with the person's web experience if you keep the encrypted data in hidden fields in the webpage.

If you wish to send out an email message to a user to view data on your website, sending an email with a link that contains encrypted data can be a way to protect people from understanding how your web pages work. It doesn't protect you too much, but the more irritating you make it, the more likely it is for someone to just not bother trying to figure out how you do things.

Conclusion

I haven't tested PHP or Python to see if they have an easy module for encrypting data. The only module that was easy to use in Perl was Blowfish. It was painful to get any others for Perl installed. If you come across any that were as easy to use, or easier than Blowish, please let me know at [email protected].


Copyright © 2000, Mark Nielsen. Copying license http://www.linuxgazette.net/copying.html
Published in Issue 59 of Linux Gazette, November 2000

[ Prev ][ Table of Contents ][ Front Page ][ Talkback ][ FAQ ][ Next ]