Alternative to crypt()
Asked Answered
M

2

6

I am working on a script and need to save passwords. For development purposes, I have been using the crypt() function because it was easy and available. Now that I am mostly done, I want to replace it with something a little better and more consistent.

Some of the concerns I have are:

  • not all algorithms are supported on every system
  • sometimes the salt is pre-pended to the result (seems like a security problem)

I want something that works with PHP 4.3+.

Is there anything available, or should I stick with crypt()? I thought about using md5(md5($password).$salt). Thanks for the insight.

Massacre answered 28/12, 2011 at 22:54 Comment(16)
You want something "better than crypt()" and you're proposing double md5?Anson
I've worked on projects where md5 and sha1 were used (not together). More info on sha1: us.php.net/sha1Oxysalt
your confusing encryption (2 way) with hashing (1 way)Williford
The salt is prepended because without it, you can't use the same salt to hash a password you want to check. It's not a security problem; in fact, it has to be there if your hashes are uniquely salted (which they should be).Adalineadall
I don't know if scrypt has been ported to PHP yet, but it is memory-hard. Which means that even high-end parallel computation systems will have a difficult time cracking any compromised digests efficiently.Borgerhout
@cHao: I have a known randomly generated salt for each user, so I do not need them remembered in the hash.Massacre
@steveo225: Consider that anyone who can get the hash, can also get the salt. You don't gain anything by storing them separately.Adalineadall
If you ever have to use PHP4 you or your bosses are doing something very, very wrong!Carrasquillo
@Borgerhout there is no scrypt implementation for PHP (I have looked), and also I would not use scrypt yet primarily because it is too young.Acariasis
@cHao: I didn't say I was storing the salt either, how the salts are maintained in not of concern, but I don't need them in the hash itselfMassacre
@Adalineadall You might get something by storing them separately... if they are stored in two different database columns then you can authenticate a user entirely in the database without any complicated parsing. ... WHERE hashed_password = SHA1(SHA1(@password) || password_salt)Borgerhout
@steveo: It's important if people knowing the salt is a security problem. If i can figure out the salt, then you have gained nothing by not having it in the hash. And if you're hashing per user, i can figure it out.Adalineadall
@cHao: What makes you think you could easily figure out the salt? That's why I don't want it in the hash... if it isn't known, isn't static, and isn't saved in the database, it is that much tougher to brute force the password.Massacre
@cdhowie: You've just sent the password, unhashed and quite possibly unencrypted, over the SQL connection.Adalineadall
@cHao: If the connection to the database server is not encrypted or at least on a private network (loopback included), there are more problems here. This can be mitigated somewhat by performing the initial SHA1 round in the application and passing that to the database.Borgerhout
@steveo: I can figure it out because you have to figure it out in order to authenticate the user. And if i have access to your database, then it's likely i own your server already.Adalineadall
A
6

There is nothing wrong with crypt

If your server does not support it, use another server.

You should NEVER use MD5 for hashing passwords (or even SHA1 for that matter)

Use either bcrypt (the blowfish method of crypt) or pbkdf2

There is an implementation of pbkdf2 here: Encrypting Passwords with PHP for Storage Using the RSA PBKDF2 Standard

More information on why and how here:

Acariasis answered 28/12, 2011 at 22:59 Comment(12)
Problem is, I am trying to make this work for other users where I do not have control of their systems and not all crypt methods are available, in fact blowfish is not on mine, although it has sha512, whereas another server I play on is just the opposite.Massacre
@Massacre well if you want to sacrifice security for portability, I'm sorry for your customers.Acariasis
What is wrong with md5? I have seen many other known script systems use it, like vBulletin?Massacre
@steveo225: Just make it configureable with a good default value. In case on some system it does not exist, another algo can be used. Additionally make the whole authentication part configureable so it's possible to integrate your application into SSO systems.Trustless
@Massacre on just our computers at my work, using CUDA I can crack 1.5 billion MD5 passwords per second tomshardware.com/reviews/password-recovery-gpu,2945.htmlAcariasis
@hakre: Luckily the system is configurable that way already, so users can override it to their liking. Its just in the setup script, I am having trouble getting all the rules in the event certain methods or functions don't exist.Massacre
Don't write a routine that will always works (then use PHPASS instead, it's made for that purpose, works on PHP 3 systems, too). Instead write a clean implementation (seriously, that part of your application is crucial) and in case some users can't have it, offer a way in your program to replace the whole function.Trustless
@hakre: I know how crucial it is, hence the question, I want something that is going to be as difficult as possible, but still useable by the users. And it is completely replaceable, there is an internal encrypt function (bad name since it hashes) that can be overridden or completely replaced, but I have to provide a default.Massacre
@Petah: You posted links to why PBKDF and bcrypt are strong solutions, but you stated "You should NEVER use MD5 for hashing passwords (or even SHA1 for that matter)", can you post a link or two describing why these hashing solutions should not be considered?Oxysalt
@DigitalPrecision The last link in the answer has some information on why SHA is weak (or rather too fast to be secure) and in the comments I posted a link to Tom's Hardware which has information on how fast weak hashing algorithms are badAcariasis
MD5 is not guaranteed to provide you a unique hash. As a result, the hash can match different passwords allowing users access if they know one of them from a rainbow table.Transmittal
SHA-256 should be solid, but the issue depends on whether the time to hash is worth it to you.Transmittal
S
4

First of all: Prepending the salt is not a security problem. Having a per-password salt is a big goodie, and it's perfectly OK to it being store alongside the pw.

Now: As long as you don't transport password hashes from one system to another, and the latter not supporting the default algorithm of the first, nothing bad will happen by definition. Since PHP 5.3 there are built-in algorithms in PHP such as Blowfish, that are guaranteed to be available.

Sandhi answered 28/12, 2011 at 23:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.