Monday, July 29, 2013

PHP Documentation Woes

This bit of php documentation has some interesting code:

 $passphrase = 'My secret';  
 /* Turn a human readable passphrase  
  * into a reproducable iv/key pair  
 $iv = substr(md5('iv'.$passphrase, true), 0, 8);  
 $key = substr(md5('pass1'.$passphrase, true) .   
         md5('pass2'.$passphrase, true), 0, 24);  
 $opts = array('iv'=>$iv, 'key'=>$key);  
 $fp = fopen('secret-file.enc', 'wb');  
 stream_filter_append($fp, 'mcrypt.tripledes', STREAM_FILTER_WRITE, $opts);  
 fwrite($fp, 'Secret secret secret data');  

3DES takes a 192-bit key (actually 168), so the first two keys are taken from the first MD5 and the third key is taken from the second MD5. I have a strong suspicion that that alignment introduces some kind of vulnerability, but I can't quite put my finger on it. If anyone knows, please leave a comment.

This tweet says it all:

Lessons Learned:
  • Don't use MD5 to derive keys from passwords. Use PBKDF2.
  • Use a random, unique IV. Don't derive it from the password.
  • Documentation will be used by many people. It's worth hiring a cryptographer to check it.

1 comment:

  1. Well I'd say that one problem with mentioned approach is that MD5 is fast while PBKDF2 is slow by design. This means that you bruteforce / run a dictionary attack on MD5 derived keys more efficiently.

    Martin Rublik