Crypt::CBC Secret Key and IV Algorithm

The algorithm used in Crypt::CBC is described for deriving the secret key and the IV from a passphrase and a salt. It is using the MD5 hash function 4 times recursively on the combination of the passphrase and the salt to produce bytes to populate the secret key and the IV.

Ok, we know to use Crypt::CBC salted key option, and how it behaves. Let's try to see how it derives the secret key and the IV from the passphrase and salt.

Unfortunately, the Crypt::CBC manual page does not give us the algorithm used to derive the secret key and the IV. I need to look at the source code at C:\local\Perl\site\lib\Crypt\CBC.pm. Here is what I found:

my ($key,$iv) = $self->_salted_key_and_iv($self->{passphrase},$salt);
...
    
function _salted_key_and_iv ($pass, $salt) {
   if(strlen($salt) != 8) {
      die("Salt must be 8 bytes long");
   }

   $key_len = 56;
   $iv_len  = 8;

   $desired_len = $key_len+$iv_len;

   $data  = '';
   $d = '';

   while (strlen($data) < $desired_len) {
      $d = pack("H*", md5($d . $pass . $salt));
      $data .= "$d";
   }

   return $data;
}

Based on the above code, we can assume that Crypt::CBC is using the following algorithm to derive the secret key and the IV from a given passphrase and a salt. It is using the MD5 hash function 4 times recursively on the combination of the passphrase and the salt to produce bytes to populate the secret key and the IV.

Input: 
   Passphrase: The passphrase of any size
   Salt: The salt of 8 bytes

Output:
   Key: The secret key of 56 bytes (448 bits)
   IV: The IV of 8 bytes (64 bits)
   
Algorithm - Salted Key Generation:
   Buffer = empty            : Open a buffer to collect hash
   
   Raw = Passphrase . Salt   : Initialize a raw byte array
   Hash = MD5(Raw)           : Generate MD5 hash of 16 bytes
   Buffer = Buffer . Hash    : Append to the buffer to 16 bytes
   
   Raw = Hash . Passphrase . Salt 
   Hash = MD5(Raw)           : Generate MD5 hash of 16 bytes
   Buffer = Buffer . Hash    : Append to the buffer to 32 bytes
   
   Raw = Hash . Passphrase . Salt 
   Hash = MD5(Raw)           : Generate MD5 hash of 16 bytes
   Buffer = Buffer . Hash    : Append to the buffer to 48 bytes

   Raw = Hash . Passphrase . Salt 
   Hash = MD5(Raw)           : Generate MD5 hash of 16 bytes
   Buffer = Buffer . Hash    : Append to the buffer to 64 bytes

   (Key, IV) = Buffer        : Split buffer to become secret key and IV

Note that this algorithm is very important for the receiver of the ciphertext, if he/she is not using Crypt::CBC to decrypt the ciphertext. He/she has to derive the secret key and the IV from the passphrase and the salt in order to other Blowfish CBC tools to decrypt the ciphertext.

Table of Contents

 About This Book

 Blowfish Cipher Algorithm

 Perl Crypt::Blowfish Module

 Perl Crypt::ECB Perl Module

Perl Crypt::CBC Module

 What is Crypt::CBC

 Installing Crypt::CBC 2.33 with ActivePerl

 Crypt::CBC Encryption with Literal Keys

 Crypt::CBC Literal Key Error Cases

 Crypt::CBC Encryption with Crypt::Blowfish Objects

 Crypt::CBC Operation Simulation

 Crypt::CBC Encryption Verification

 Blowfish CBC 2-Block Test Vectors

 Crypt::CBC Prepending IV to Ciphertext

 Crypt::CBC Encryption with Salted Keys

 Crypt::CBC Salted Key Test Cases

Crypt::CBC Secret Key and IV Algorithm

 Crypt::CBC Encryption with Random Salt

 Crypt::CBC Padding Options

 Crypt::CBC Padding Option Tests

 Crypt::CBC Blowfish Encryption Summary

 Perl Crypt::CFB Perl Module

 OpenSSL "enc -bf-ecb" for Blowfish/ECB Encryption

 OpenSSL "enc -bf-cbc" for Blowfish/CBC Encryption

 OpenSSL "enc -bf-cfb" for Blowfish/CFB Encryption

 OpenSSL "enc -bf-ofb" for Blowfish/OFB Encryption

 PHP Mcrypt Extension for Blowfish

 Blowfish 8-Bit Cipher in PHP

 References

 Full Version in PDF/EPUB