﻿ ﻿
﻿

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.

﻿

﻿ ﻿