Wednesday, July 10, 2013

CodeIgniter: Another rand() Stream Cipher

When the mcrypt functions are missing, the CodeIgniter PHP framework falls back to a homebrew stream cipher it calls "xor_encode."

 protected function _xor_encode($string, $key)  
 {  
      $rand = '';  
      do  
      {  
           $rand .= mt_rand();  
      }  
      while (strlen($rand) < 32);  
   
      $rand = $this->hash($rand);  
   
      $enc = '';  
      for ($i = 0, $ls = strlen($string), $lr = strlen($rand); $i < $ls; $i++)  
      {  
           $enc .= $rand[($i % $lr)].($rand[($i % $lr)] ^ $string[$i]);  
      }  
   
      return $this->_xor_merge($enc, $key);  
 }  
   
 protected function _xor_merge($string, $key)  
 {  
      $hash = $this->hash($key);  
      $str = '';  
      for ($i = 0, $ls = strlen($string), $lh = strlen($hash); $i < $ls; $i++)  
      {  
           $str .= $string[$i] ^ $hash[($i % $lh)];  
      }  
   
      return $str;  
 }  

Lessons Learned:
  • Don't invent your own cipher.
  • If your cryptography library is missing, don't encrypt! If you really need to fall back, include a well-tested implementation of a good cipher.

No comments:

Post a Comment