Search This Blog

Wednesday, 31 December 2014

Encoding, encryption and hashing basics with Perl examples

Encoding, encryption and hashing are about data transformation. While encoding and encryption are reversible (given the output and some additional information, the input can be obtained), hashing is a one way, irreversible. change.

                                   processing                                         purpose
          ------------------------------------------------------------------------------------------------------------
          Encoding:     data + algorithm                     => for transfer and consumation purposes
          Encryption:  data + algorithm + secret key  => for secure transfer
          Hashing:       data + hash function               => for data integrity, for sender identification, fast search for a data record, building caches

 

Encoding


Encoding uses a publicly available algorithm and a reverse process can be used to get at the original data. Its purpose is to provide a format that allows data to be transferred and consumed by a different system. It does not solve security issues. Examples are base64, unicode, URL/HTML encoding etc.

Example:

A)

my $ip         = '192.168.2.100';
my $ip_encoded = unpack('N', pack('C4', split(/\D/, $ip, 4))); 

(pack creates a string concatenated from 4 unsigned chars/octets (in machine form) of the IP address. unpack transforms this string into an unsigned long (32 bit) in "network" (big endian) order.)

B)
Base64 encoding (radix-64 representation) is widely used to represent binary data in text format, used for data transport.

CGI script:

use strict;
use warnings;

use CGI;
use JSON;
use MIME::Base64;

my $cgi = CGI->new();

my $image_file = "/var/www/images/sunflower.jpg";

undef $/;
open  my $fhandle, '<', $image_file;
my $image = <$fhandle>;

$image_encoded = encode_base64($image);
my $response = to_json({ photo => $image_encoded });

print $cgi->header(-Content_type => 'application/json');
print $response 
 
Then on the web page: 

<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>Encode64 Example</title>
    <script src="jquery-1.2.1.min.js" type="text/javascript" charset="utf-8"></script>
  </head>
  <body>
    <p>Encode64 Example</p>
    <script>
       $(document).ready(function () {

            $.getJSON('/test_my_app',  function(data) {
               var photo = data.photo;      // contains the encoded contents of the image 

               var elems  = [];

               elems.push('<table>');
               elems.push('<tr>');

               elems.push('<td id="photo">' +  
                          '<img src="data:image/jpg;base64, ' + photo + '" />' + 
                          '</td>');

               elems.push('</tr>'); 
               elems.push('</table>');

               $('body').append(elems.join(''));
           });

       });
    </script>
  </body>
</html>  

 

Encryption


While an encrypted message can be decrypted to provide the original plain text, decryption can only be carried out by those who know a key, that was used together with a particular algorithm during the encryption. Encrypted data can be, therefore, securely transferred to the desired recipient.

Example


use strict;
use warnings;
use utf8;
use v5.018;
use Crypt::CBC;

my $plaintext  = "World's biggest secret";
my $cipher     = Crypt::CBC->new( -key    => 'my_secret_key',
                                  -cipher => 'Blowfish',
                               );  

my $ciphertext = $cipher->encrypt($plaintext);
$plaintext     = $cipher->decrypt($ciphertext);

say "$plaintext";

Hashing


Hashing transforms an arbitrary string of characters into a fixed-length string through the use of a hash function. The resulting hash value/hash sum/hash/message digest should be be always the same for the same input, and it is should be practically impossible, ie computationally infeasible, to invert/find the original value from the hash. A hashing function should never produce the same hash for two different inputs. Hashing is used for checking data integrity, sender's identity etc.

Perl modules:
               Digest::SHA
               Crypt::PBKDF2 etc

Examples


use Digest::SHA qw(sha256_hex);
$data = "this is top secret";

$digest = sha256_hex($data);


use Crypt::PBKDF2;

my $pbkdf2 = Crypt::PBKDF2->new(
                  hash_class => 'HMACSHA1' # default, other functions available
                  iterations => 120000,    
                  output_len => 25,        
                  salt_len   => 4,           
);

my $hash = $pbkdf2->generate("my_biggest_secret");
# store in database

# later on, somebody logs in
# retrieve the person's hash from the database
# check the password
if ($pbkdf2->validate($hash, $password)) { .... }

No comments: