Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I vendorize bcrypt in a PHP application (and should I)?

I am contributing to a relatively mature open-source PHP project. Recently, I discovered that it stores passwords as plain MD5 hashes, which is quite bothersome to me. I figured that if I was going to fix it, I might as well Do It Right(tm), so I wanted to use bcrypt.

First, what I have found for other languages: bcrypt-ruby appears to use either the original C code from OpenBSD or jBCrypt's java code. py-bcrypt is a thin wrapper around the BSD code. BCrypt.net is a direct port of jBCrypt.

Now, PHP itself supports bcrypt (albeit, misleadingly called simply 'blowfish') in the crypt function. However, versions prior to 5.3 require support on the system itself, generally provided by crypt_blowfish. phpass is the same, and recommends installing either PHP 5.3 or Suhosin.

Since many users of the application use standard shared hosting, I don't want to require any special configuration of the server. I was hoping to just steal the code from PHP's 5.3 release, but it is in C, and (from the small bit of reading I've just done) I cannot require the use of a C-extension for the project's users.

I thought of just creating a pure-PHP port of bcrypt, but looking at the source of jBCrypt, I am not sure that I should, given that I'm not incredibly familiar with either PHP or blowfish, and a mistake here could be simultaneously dangerous and difficult to detect in the first place.

So, I present to you two (multipart) questions:

  1. Is my lack of PHP knowledge getting the best of me? Can I really use one of the already-created implementations?
  2. Should I instead just create a simple loooping function that calls sha1() or md5() repeatedly for some configurable number of times?
like image 476
Xiong Chiamiov Avatar asked Aug 23 '10 23:08

Xiong Chiamiov


2 Answers

Is my lack of PHP knowledge getting the best of me? Can I really use one of the already-created implementations?

Unfortunately, you are correct. Prior to 5.3.0 PHP didn't support bcrypt by default. Instead, it relied on the OS's support (check the CRYPT_BLOWFISH constant). As you've pointed out Suhosin is an option in that case.

Should I instead just create a simple loooping function that calls sha1() or md5() repeatedly for some configurable number of times?

The best advice when it comes to cryptography is "don't roll your own." Repeated calls to sha1() or md5() may or may not increase security.

The authors of bcrypt on the other hand explain their design decisions on this paper.

like image 189
NullUserException Avatar answered Sep 20 '22 06:09

NullUserException


Unfortunately you can't use bcrypt with Blowfish unless you're on PHP 5.3 or using the Suhosin extension or possibly that the operating system has support for Blowfish in its bcrypt implementation.

So your best bet in this case would be to use SHA-256 or SHA-512 with key stretching (and of course, salt). But rolling your own solution is never a good idea when it comes to security.

like image 45
Christian Davén Avatar answered Sep 20 '22 06:09

Christian Davén