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.

Last update: 2015.

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