12

I am using Code Igniter for my current project.

As of now, I am using MD5 for password hashing, but I have read at a lot of places, that it is not a good practice to do so.

What should I go with?

  1. Using a salt
  2. Or should I use bcrypt

Also, if bcrypt is recommended, then how to use it with Code Igniter?

EDIT

I have put these files in application/libraries

  1. PasswordHash.php
  2. c/Makefile
  3. c/crypt_private.c

In my controller, I am using this code -

$params = array(
       'phpass_hash_strength' => 8,
           'phpass_hash_portable' => FALSE
       );
$this->load->library('PasswordHash', $params);
$password = $this->passwordhash->HashPassword($pwd);

I am getting these errors -

A PHP Error was encountered

Severity: Notice

Message: Uninitialized string offset: 3

Filename: libraries/PasswordHash.php

Line Number: 116

A PHP Error was encountered

Severity: Warning

Message: strpos() [function.strpos]: Empty delimiter

Filename: libraries/PasswordHash.php

Line Number: 116

Update

Removed PasswordHash.php, using SimpleLoginSecure now.

Emil Laine
  • 41,598
  • 9
  • 101
  • 157
Aniket
  • 9,622
  • 5
  • 40
  • 62

3 Answers3

16

Use bcrypt. This discussion came up here in the comments to my answer. You can use a library such as phppass to really simplify the password encryption.

On the matter of salt. Use it! Otherwise somebody can simply go to this site and download the rainbow tables that will cover the large majority of passwords the average users chooses. Especially with all the security leaks in the last few months, now is not the time to be saying you won't use something as simple to implement as random salt.

UPDATE

To use PHPPass with CI, download and extract the files from the phppass website, linked above. Put the PasswordHash.php file into your CI application/libraries directory.

In your code, you then load the library via: $this->load->library('PasswordHash',array(8, FALSE));

Hashing passwords is then as simple as $this->PasswordHash->HashPassword($password);

To later check if a password is correct, it is as simple as:

$password = $_POST['password'];
$actualPassword = /*Get the hashed password from your db*/;

$check = $this->PasswordHash->CheckPassword($password, $actualPassword);

I've taken this demo from http://dev.myunv.com/articles/secure-passwords-with-phpass/ which gives you a lot more informations. I've modified that tutorial slightly to utilize CI's loader which is why you don't need the include or new statements.

Community
  • 1
  • 1
Endophage
  • 21,038
  • 13
  • 59
  • 90
  • 1
    So what would be better? Using SHA1 or bcrypt? – Aniket Aug 12 '11 at 19:03
  • 1
    @Aniket bcrypt is massively more secure. As I said, read the comments on my other answer to find out why. In short though, calculating the rainbow tables for bcrypt is massively more expensive than for even SHA2 (note SHA1 is dead, don't even go there, I should have said that earlier). – Endophage Aug 12 '11 at 19:05
  • Could you tell, how to use bcrypt with CI? Is it a separate library which I can add to my project? – Aniket Aug 12 '11 at 19:07
  • I am running hash('sha512'); with the unix datestamp(date of register) as a salt. Works well. If you dont use bcrypt be sure and always use a salt – Brad Aug 12 '11 at 22:47
  • @Brad read this article to see why bcrypt is still a significantly better option http://codahale.com/how-to-safely-store-a-password/ – Endophage Aug 12 '11 at 22:52
  • @ Endophage Thanks, I wasnt asserting one was better that the other, just that hash 512 was available and all encrypt ions need to be salted. I will most certainly read your link and see if I can redo my current system if needed with bcrypt – Brad Aug 12 '11 at 22:56
  • 1
    @Brad bcrypt is pretty nice in that the salt is built in which saves you needing to create and store it. – Endophage Aug 12 '11 at 22:58
  • @Endophage Not able to use the PasswordHash library. I have put all the files in my application/library . But it is giving this error - `A PHP Error was encountered Severity: Notice Message: Undefined property: Main::$PasswordHash Filename: controllers/main.php Line Number: 59 ` – Aniket Aug 13 '11 at 18:12
  • @Endophage Now that part worked, I am getting these errors now ... :| `A PHP Error was encountered Severity: Notice Message: Uninitialized string offset: 3 Filename: libraries/PasswordHash.php Line Number: 116` AND `A PHP Error was encountered Severity: Warning Message: strpos() [function.strpos]: Empty delimiter Filename: libraries/PasswordHash.php Line Number: 116` – Aniket Aug 13 '11 at 18:36
  • @Aniket can you add what code you've written so far to your original question. I'll see if I can replicate the error. – Endophage Aug 13 '11 at 22:44
  • @Endophage - Upon using `$this->load->library('PasswordHash', array(8, FALSE));`, I am receiving the following error: `A PHP Error was encountered; Severity: Warning; Message: Missing argument 2 for PasswordHash::PasswordHash(), called in C:\testsite\system\core\Loader.php on line 1095 and defined; Filename: libraries/PasswordHash.php; Line Number: 33`. Your help will be very much valuable! – Nirmal Dec 22 '11 at 21:30
  • @Nirmal please try debugging yourself first. Then, ask as a new question if you can't figure it out. Note, the OP switched to use SimpleLoginSecure instead of PHPPass. I still stand by using bcrypt but if a different library makes it easier to use than PHPPass then you should prefer that implementation. – Endophage Dec 26 '11 at 19:08
  • @Endophage - A typo broke the code. Fixed now. After reading about bcrypt in many places, I am not convinced to leave it beside other solutions. Thanks! – Nirmal Jan 14 '12 at 16:00
  • 1
    what typo? i'm having the same error `Missing argument 2 ...` – b_dubb Dec 27 '12 at 00:53
  • 1
    also the http://dev.myunv.com/articles/secure-passwords-with-phpass/ link is dead so that's no longer helpful – b_dubb Dec 27 '12 at 01:23
5

why use md5() when it is just as easy to use sha1() ?

Also salting the passwords is always a good idea as it effectively removes the threat of a Rainbow Table attack

In my experience a salted SHA1 hash is pleanty secure for 99% of web application situations.

jondavidjohn
  • 61,812
  • 21
  • 118
  • 158
  • I don't plan to use a salt. So I should use SHA1? – Aniket Aug 12 '11 at 18:50
  • 1
    there is no reason in my opinion to use md5 when sha1 is so readily available in php. – jondavidjohn Aug 12 '11 at 18:52
  • I will need to change my code a little more for that :P whereas for SHA1, I can go ahead and just replace the MD5 with it. – Aniket Aug 12 '11 at 18:55
  • 2
    And CI has encryption functions which use an encryption key you set in the config, tying it to your particular application. So, just use `$this->ci->hash($password);` and it will use sha1 if it's available on your server. CI docs: http://codeigniter.com/user_guide/libraries/encryption.html – permawash Aug 12 '11 at 19:00
  • @permawash you need random salt for security. Using CI's encryption key as salt it a poor substitute. CI just provides that use of it for people who are inexperienced or too lazy to do proper security. See my answer and the link to my other answer where discussions related to this took place. – Endophage Aug 12 '11 at 19:03
  • So, if i use `$this->ci->hash($password);` this, it would automatically make use of SHA1?? – Aniket Aug 12 '11 at 19:04
  • unless he's building the NSA's new hip codeigniter web app, i doubt a salted sha1 won't be sufficient. – jondavidjohn Aug 12 '11 at 19:05
  • 3
    @jondavidjohn given how easy good security is to implement there is absolutely no excuse for risking an intrusion because as the developer, you couldn't be bothered, no matter how small your website is. – Endophage Aug 12 '11 at 19:21
3

Code Igniter has changed since the time this question was asked. But for the benefit of some who may not have come across the extensive documentation of CI or haven't seen this before, CI has an encryption class which provides a two-way data encryption using the Mcrypt library of PHP.

After initializing the class using:

$this->load->library('encrypt');

You can encrypt as follows:

$msg = 'My secret message';
$encrypted_string = $this->encrypt->encode($msg);

and decrypt as follows:

$encrypted_string = 'APANtByIGI1BpVXZTJgcsAG8GZl8pdwwa84';
$plaintext_string = $this->encrypt->decode($encrypted_string);

CI also has a non-decodable 1-way hashing:

$hash = $this->encrypt->sha1('Some string');

For more information see: http://www.codeigniter.com/user_guide/libraries/encryption.html

Ibrahim Dauda
  • 645
  • 8
  • 19
  • 8
    First paragraph from the indicated link: **DO NOT use this or any other encryption library for user password storage! Passwords must be hashed instead** – Starlays Sep 22 '16 at 17:09