11.1.2.3 Secure Message Digests or Message Authentication Codes

11.1.2.3  Secure Message Digests or Message Authentication Codes

     

A message digest, by itself, does not give us a very high level of security. In the examples in section 11.1.2.2, we can determine if a file has been corrupted because the content of the file will not produce the same message digest that was produced earlier. But, there is no way to prevent someone from changing both the “secured” file and the accompanying digest file so that the new digest file reflects the altered content of the new “secured” file.

There are several ways in which a message digest can be made into a message authentication code (MAC). Below, we discuss a technique that uses a passphrase with the message digest to calculate a secure message digest. A passphrase is a “password” that can have several words in it. We call this a MAC. For the MAC approach to work, it is necessary that both the sender and the receiver of the secured file or data, have a shared passphrase. The two communicating parties have to agree on a way to create the passphrase, exchange it securely, and then keep it secret as long as they use it.

 Program 11.5

#!/usr/bin/perl
#file md5SecureFile.pl
use strict;
use Digest::MD5;

######
#subroutine to create .mac file
######
sub computeSecureMd5Digest{
   my ($file) = @_;
   my ($context, $digest, $passphrase, $mac);

   #Read passphrase from the terminal
   print "What is your passphrase?: ";
   $passphrase = ;
   chomp ($passphrase);

   #Create hash context and add the file content
   $context = Digest::MD5 -> new();
   open (FILE, $file) or die "$file doesn't exist: $!";
   $context -> addfile (*FILE);
   close $file;

   #add the passphrase to the hash context
   $context -> add ($passphrase);
   #compute the digest of file content + passphrase
   $digest = $context -> digest ();

   $context -> reset ();
   #Again, calculate digest or MAC, of the passphrase and first digest
   $context -> add ($passphrase);
   $context -> add ($digest);
   $mac = $context -> digest ();
   print "MAC saved in file $file.mac = ", unpack ("H*",  $mac), "\n";

   #Write MAC into a file with extension .mac
   open MAC, ">$file.mac";
   print MAC $mac;
   close MAC;
}

#main 
my ($file) = $ARGV[0];
&computeSecureMd5Digest ($file);

The name of the file to secure is given as a command-line argument to the program md5SecureFile.pl. Here, corresponding to a secured file, we create a new file with the .mac extension appended to its end.

The main program calls the subroutine computeSecureMd5Digest with the name of the file as an argument. The subroutine prompts the user for a passphrase, and then, creates an MD5 digest called $digest that is a fingerprint of the content of the file to be secured and the passphrase. Note that this first digest computed is not stored in the accompanying .mac file. What we have done is computed a “secure” digest which, in a sense, takes the passphrase as key; and then, secured this “secure” digest again by computing a new digest, which we call the MAC. The computation of the MAC uses the passphrase a second time. In other words, we are “doubly secure.” The MAC or the second digest is stored in the .mac file.

For this technique for securing the integrity of a file to work, the passphrase cannot be transmitted along with the original file and the accompanying .mac file. Both the original file and the .mac file need to be given by the sender to the receiver. The transmission can take place by various means such as e-mail attachments, ftping of the files, through the use of a floppy disk, CD, or a zip disk, etc. The passphrase must be transmitted using another channel, preferably secure, such as telephone, secure e-mail, hand exchange, certified surface mail, etc. Note that a telephone conversation is not really secure.

A sample interaction with the program is given below.

 

%md5SecureFile.pl jk1.jpg

What is your passphrase?: It was the best of times, it was the worst of times.

MAC saved in file jk1.jpg.mac = 69f5a2c1dc6834a6c32d9d414c19da4d

 

The program asks for a passphrase which the user gives as It was the best of times, it was the worst of times. including the period. The program computes the secure message digest or the MAC and stores it in the accompanying .mac file.

For verification of the integrity of the “secured” file, the reverse process has to be performed at the receiver’s end. The following program accomplishes this for us.

 Program 11.6

#!/usr/bin/perl
#file md5SecureFileVerify.pl
use strict;
use Digest::MD5;

##subroutine to verify a secured MD5 file digest
sub verifySecureMd5Digest{
   my ($file) = @_;
   my ($passphrase, $context, $digest, $mac, $macInFile);

   if (!(-e "$file.mac")){
      print "There is no MAC file: $file.mac\n";
      print "Conclusion: The file $file is not original\n";
      exit;
    }

   #Read passphrase from the terminal
   print "What is your passphrase?: ";
   $passphrase = ;
   chomp ($passphrase);

   #Create hash context and add the file content
   $context = Digest::MD5 -> new();
   open (FILE, $file) or die "$file doesn't exist: $!";
   $context -> addfile (*FILE);
   close $file;

   #add the passphrase to the hash context
   $context -> add ($passphrase);
   #compute the digest of file content + passphrase
   $digest = $context -> digest ();

   $context -> reset ();
   #Again, calculate digest or MAC, of the passphrase and first digest
   $context -> add ($passphrase);
   $context -> add ($digest);
   $mac = $context -> digest ();
   print "MAC computed on file $file = ", unpack ("H*",  $mac), "\n";

   #Read the MAC saved in the .mac file
   open MAC, "$file.mac";
   $macInFile = ;
   chomp ($macInFile);
   close MAC;
   
   #Compare $mac and $macInFile
   if ($mac eq $macInFile){
      print "Conclusion: File $file is original\n";
    }
   else{
      print "Conclusion: File $file is NOT original\n";
    }
}

#main
my ($file) = $ARGV[0];
&verifySecureMd5Digest ($file);

 

The program takes a file to verify for integrity as command-line argument. The main program calls the subroutine verifySecureMD5Digest that does all the work. If a corresponding .mac file does not exist, the program declares that the file has been tampered with and exits. Otherwise, it asks for a passphrase. The same passphrase that was used for creating the hash has to be entered by the verifying user. It computes the two digests as it did in the MAC creation program discussed earlier. It compares the MAC read from the .mac file and the newly computed MAC on the contents of the “secured” file. If the two MACs are equal, it declares that the file being verified is original.

A couple of interactions with this program are given below.

 

%md5SecureFileVerify.pl jk1.jpg

What is your passphrase?: It was the best of times, it was the worst of times.

MAC computed on file jk1.jpg = 69f5a2c1dc6834a6c32d9d414c19da4d

Conclusion: File jk1.jpg is original

 

 

%md5SecureFileVerify.pl jk1.jpg

What is your passphrase?: It was the best of times it was the worst of times

MAC computed on file jk1.jpg = 2795116abd77d3af586e5fff64f8e5f2

Conclusion: File jk1.jpg is NOT original

 

In the second run, the passphrase given was devoid of punctuation and hence it was not acceptable.