Jump to content

Recommended Posts

  • Replies 53
  • Created
  • Last Reply

Top Posters In This Topic

Hello

 

I had a query on salting passwords, i saw this thread so felt like posting here. I found this code somewhere in the internet and modified a bit. Just want to know how feasible is this code? (feasible in the sense of security).

 

<?php
function smhs($password,$algorithm="sha256"){
$salt=sha1(md5($password));
$hashedpassword=hash($algorithm,$salt.$password);
return $hashedpassword;
}

echo smhs("mypassword");
?>

thanks

Well, any salt is better than no salt. But, if you are going to salt, then the salt should not be a "constant" and/or based on the password itself. Although the salt in the above function would be variable, because it is based upon the password it would be a trivial exercise to brute force ALL the hashed passwords at one time.

 

For example, if two users had the same password, the function above would produce the same hashed value. So an attacker only needs to crack one to get both values. A better approach is to use some piece of data that is unique to the user but which would not change. That way an attacker would have to brute for each password individually. Examples would be user ID, a timestamp of when the user signed up, etc.

 

Then change the function to accept both the password and the salt.

function smhs($password, $salt, $algorithm="sha256")
{
return hash($algorithm, $salt. $password);
}

Why not continue this thread until we all die!

 

I wrote the login system for a large social network.  The salts were unique for every user, and they were not values exposed to the user in any way.  Also, the mod of another user-unique value was used to determine which of our 2 rotating cyphers would be used first.

 

 

Most people use the same passwords for other sites.  Online banking, financial services, facebook, etc.  And if not the same, only a small change.  This would be the reason why the hacker would want this information.

 

Only if you don't take security seriously, I have had to nearly beat into my family members this truth.  I have one password for forums, I have one password for banks, and I have seven passwords for each of my email addresses which I rotate on a yearly basis.

 

My question is this with the md5/salt passwords.

 

Basic 101 coding I was told to do a SHA() for the password... so it wouldn't show up in plain text, could you use that, plus md5/salt to make it more secure?

 

Also lets just take it as this, people here are taking the concept that a password is actually going to be a word, and a few numbers perhaps to make it more complex to crack... what about those like me that don't?

 

One password, lets just say someone wishes to use the plain text version would be Quinn, I might make it Qu!^!^!. 

 

Now lets just say I use an SHA() code with that, would it be advantageous of me to also thrust into it md5/salt as well? Or is the md5 the SHA() code already?

 

Sorry if I sound dense, but I need to find these things out for my own stuff since what I am doing is going to be demanding utter security for my database when it's complete. 

 

 

I've already printed out the How to Manage a PHP application's user and password document, but I was wondering if there was another level of security you could put on top of it to make it more secure.

Yes, I told you. USE THE CLASS THAT I HAVE LINKED IN MY SIGNATURE

 

It uses key lengthening. Do you realize my mid-range 4 year old graphics card can calculate hundreds of millions of SHA-1 hashes per second?

 

Matt Ridge - You are not a cryptographic expert. Please do not try to come to any reasonable conclusion about security if you don't completely understand it. The best thing we can do is leave it to the people smarter than us and implement what they make. That's why we use things SHA-1 and not some home-brew one-way algo.

Matt, if a company with a breached password database said "well maybe you should have taken security more seriously" instead of apologizing, their customers would sue en masse (unless they're PS3 customers, naturally).

 

The article in xyph's signature (which we really couldn't point out more unless I physically changed it to a big blinking box at this point) covers the answer to your next question about sha/md5, as well as later questions in your post.

 

As for "what if my password is Qu!&!&!" or whatever: the larger the rainbow table, the more likely it will include random characters.  A rainbow table of the entire english language is only 5mb.  Including special characters, exclamation points, 1337-speak, and other variants would increase that size to 20mb maybe.  Still not the biggest database and a comparison to an unsalted users table wouldn't take more than a few minutes.

 

This is (roughly) what I did to make my site secure.  Example variables with descriptive names are used.  $secretSalt was an alphanumeric string that we generated when the user logged in.  Also note that as an example I used md5 and sha1 in this example, read xyph's article for more correct information.

 

if ( $userId % 2 ) {
  $encryptedPass = md5(sha1($password . $secretSalt));
} else {
  $encryptedPass = sha1(md5($secretSalt . $password));
}

-Dan

IMO If you're going to use multiple cyphers, I'd suggest they be the same bit length - Make it less obvious you're implementing two different cyphers.

 

I know this is slightly trivial in the grand scheme of things and your snippet was just an example, but it's worth mentioning.

@xyph

 

I never said I was a cryptography expert. I was pointing out a lot of people here were throwing examples of dictionary based words, which if even unknown could be figured out through a generic brute force system, with the use of a good dictionary. 

 

A lot of people use birth dates, pet names, or something all together researchable.

 

I have been dealing with generic IT and networking security for over 20 years. I have been dealing with the hardware aspect of computers probably longer than most people here have been around computers. I know more about network security and hardware security than most people. I was working on computers back in 1980, and fixing them in 82.

 

I am new to the web side, especially php and SQL.

 

When it comes to computer hardware, and intranet I know a lot. Just not the other aspect of it. So sorry if you took it as me saying I know as much as you, because I never said I do.

 

I was simply asking, if there was anything else than the combination offered that would be bennifical. I was asking about the SHA, and how it plays into this. Because I honestly wanted to know. I was not asking to be an ass.

 

I said I downloaded your document to show I am interested in learning, but I wanted to know something before delving into it this weekend.

 

@ManiacDan

 

I know about the link and already said I was reading it. I just wanted clarification on some things because to me it seems that genetic passwords with no special character attached seems to be asking for trouble. I was giving an example. That's all.

 

Thanks for explaining about rainbow attacks. I'm still trying to learn.

 

@  Both of you.

 

Don't assume someone posting here asking a question is doing it to be an ass. I was being serious when asking why not use SHA, I didn't know if that was "salt" or what.

 

I don't assume when people call me to set up a network that they know what they really want. I listen and try to figure out what they want compared to what they need, and I never talk down to them or treat them like dirt because they ask a question that you think is stupid.

 

Sometimes the only way to learn is to ask dumb questions, because then you learn and perhaps will ask the right ones later.

 

I know Xyph has a link that explains a lot, but perhaps I was asking because it is good to get insight from a person. Instead of being told to read what they wrote instead.

 

It's like having a teacher saying read the book but don't ask me any questions because I don't want to answer them. At least that is how I feel right now.

 

 

The point is my link answers just about every question you have asked in this thread. It was written by someone who understands these concepts better than just about, if not everyone on this board.

 

This is more like someone you've asked for advice admitting they're not an expert in the field, and pointing you to a resource written by someone who is.

 

It's like having a teacher saying read the book but don't ask me any questions because I don't want to answer them. At least that is how I feel right now.

I feel sorry for any teachers whom had to put up with you.

 

http://player.vimeo.com/video/11328554

The point is my link answers just about every question you have asked in this thread. It was written by someone who understands these concepts better than just about, if not everyone on this board.

 

This is more like someone you've asked for advice admitting they're not an expert in the field, and pointing you to a resource written by someone who is.

 

It's like having a teacher saying read the book but don't ask me any questions because I don't want to answer them. At least that is how I feel right now.

I feel sorry for any teachers whom had to put up with you.

 

http://player.vimeo.com/video/11328554

 

You may be right about your link, but if the topic keeps coming up then perhaps it doesn't answer all the questions, or perhaps that people prefer human interaction instead of being told to read something that at this point in time they don't comprehend? Like me... I'm new to this type of concept, so going head into security like the link states doesn't help me, yes it explains a lot but as you have noticed with my posts I am still getting down the concepts of PHP structure, so staying read my link and you'll understand everything you will never ask is not exactly true.

 

If I don't understand the basic concepts of formatting, how do you expect me to comprehend the complexities of php security language and coding?

 

Just saying...

 

As for the pot shot about the teacher thing and me... poor form.

 

 

Alright guys, let's try to calm down. 

 

Matt, we're perfectly willing to answer any questions you have, but what you said was "I acknowledge that you told me to read the article, and I have not yet read it, but I have some questions here that are covered in the article which you've told me to read and I still have not read."  Nobody is going to respond favorably to that, not random posters on the internet and not even your teacher (whom is paid to put up with it).  Read the article, and come back if you still have questions. 

 

If you've read the article and you still have questions, then please let's discuss it. 

 

If I don't understand the basic concepts of formatting, how do you expect me to comprehend the complexities of php security language and coding?
We don't, that's why we provided you with a 10 page article about the topic which includes an entire encryption class you can download and use without understanding how or why it works. 

 

We're not trying to be jerks, but you're in well over your head and continued to ask relatively basic questions while admitting that you hadn't read the article that answers them.  Go read.  Come back when you're done and we'll continue.  Good questions should be in the format of "the article says <quote> but I don't quite understand why"

Alright guys, let's try to calm down. 

 

Matt, we're perfectly willing to answer any questions you have, but what you said was "I acknowledge that you told me to read the article, and I have not yet read it, but I have some questions here that are covered in the article which you've told me to read and I still have not read."  Nobody is going to respond favorably to that, not random posters on the internet and not even your teacher (whom is paid to put up with it).  Read the article, and come back if you still have questions. 

 

If you've read the article and you still have questions, then please let's discuss it. 

 

If I don't understand the basic concepts of formatting, how do you expect me to comprehend the complexities of php security language and coding?
We don't, that's why we provided you with a 10 page article about the topic which includes an entire encryption class you can download and use without understanding how or why it works. 

 

We're not trying to be jerks, but you're in well over your head and continued to ask relatively basic questions while admitting that you hadn't read the article that answers them.  Go read.  Come back when you're done and we'll continue.  Good questions should be in the format of "the article says <quote> but I don't quite understand why"

 

I'm sorry I spent all weekend attempting to understand the 10/20 page document that was linked to, I have more questions than answers, and a headache to match.

 

Here is my list:

 

1. Avoid leaking server setup details:

 

What in the script shown originally actually dictates that it is ok to show the script? Better yet, how do you make it so that the code only allows local systems to debug instead of allowing everyone in the world to see it?

 

How would the administrator administrate said server to allow or disallow such function?

 

2. Input filtering.

 

It states that it sanitizes, but no where does it explain what each line is actually doing.  To me it is gibberish, and makes no sense upon why the code actually works. I'd like to say I'm not copying and pasting code just to make something work without knowing what it actually is doing, and why.

 

3. How to enforce a password policy.

 

Yes I know pwqcheck means password/passphrase strength checking and enforcement; but I have no clue what the code inside:

 

function pwqcheck($newpass, $oldpass = '', $user = '', $aux = '', $args = '')
{
// pwqcheck(1) itself returns the same message on internal error
$retval = 'Bad passphrase (check failed)';

$descriptorspec = array(
	0 => array('pipe', 'r'),
	1 => array('pipe', 'w'));
// Leave stderr (fd 2) pointing to where it is, likely to error_log

// Replace characters that would violate the protocol
$newpass = strtr($newpass, "\n", '.');
$oldpass = strtr($oldpass, "\n", '.');
$user = strtr($user, "\n:", '..');

// Trigger a "too short" rather than "is the same" message in this special case
if (!$newpass && !$oldpass)
	$oldpass = '.';

if ($args)
	$args = ' ' . $args;
if (!$user)
	$args = ' -2' . $args; // passwdqc 1.2.0+

$command = 'exec '; // No need to keep the shell process around on Unix
$command .= 'pwqcheck' . $args;
if (!($process = @proc_open($command, $descriptorspec, $pipes)))
	return $retval;

$err = 0;
fwrite($pipes[0], "$newpass\n$oldpass\n") || $err = 1;
if ($user)
	fwrite($pipes[0], "$user::::$aux:/:\n") || $err = 1;
fclose($pipes[0]) || $err = 1;
($output = stream_get_contents($pipes[1])) || $err = 1;
fclose($pipes[1]);

$status = proc_close($process);

// There must be a linefeed character at the end.  Remove it.
if (substr($output, -1) === "\n")
	$output = substr($output, 0, -1);
else
	$err = 1;

if ($err === 0 && ($status === 0 || $output !== 'OK'))
	$retval = $output;

return $retval;
}

 

Means. I understand sparse few lines in here, remember I said I am still learning the foundation of PHP and SQL interaction, throwing lines like this at me is useless.  You can say it works to do x, but without comprehending the reasoning and the functions of said lines I may as well be a student memorizing a book and not understanding what I am saying.

 

I hate to say this I read the document but comprehended very little of it. Yes I read it, and I understand what it is attempting to say, but it does not explain to me in great detail why it is doing what it is doing. Yes it shows the code on how to make it work, but it doesn't explain to me why the code works.

 

Code showing me that:

 


<?php
echo '<p>The Cat is White!</p>';
?>

 

That this will show online in a page on the web the words "The Cat is White!". It does not explain to me why it does it.

 

Yes I understand the basics of PHP, and a decent amount of HTML/XHTML, but when you say code like above, I have no clue why it works together.  When you say, this will keep people out, and put in the php // comments, and expect me to understand, sorry... I just don't... I don't enjoy just copy and pasting code and expect it to hold without knowing what it does, because it if breaks my code I want to know not only how to fix it but what it does as a whole and in pieces.

-----------------------------

 

So I will ask again, when people put SHA() to encode a password, would it be beneficial to MD5 SHA, and salt? Also, how does the server know how to use salt, or interpret it.

 

Better question is what is salt? Yes it describes the function of salt, but it doesn't exactly say what salt does except "Salts are likely-unique values that are entered into a password hashing method along with the password, which results in the same password hashing into completely different hash values given different salts."...

 

To me it says that salt adds characters into a name/password to make it harder to guess, but isn't that what SHA does? So why use salt? if SHAs are easy to hack, shouldn't it conclude that Salts are easy to hack? The only reason I ask, is simple.  People say that SHA and Salts produce random codes, I can guarantee you though that if you create a password, well lets just say the password is password, and use salt on your computer and mine the salt output should be identical, and by that response wouldn't it be understandable that if the similarity are figured out it should be crackable? 

 

The reason I can say this is because program using mathematical calculations no matter how random people think it is, can be calculated because no computer program has yet shown to be truly random, even today's AIs that are "smart" are predictable. Hence why humans can still beat computer games. The only place I know of that has a random code generator is MIT, and that is because they use a laser to encode a password by taking the geometry of the insides of a lava lamp, and produces it into a mathematical answer, and only outputs the first or last 40 integers of the calculation.

 

People here I expect will be mad at me for saying salt is crackable, but as far as I have been working on computers and networks, I have seen technology come out and say its uncrackable, yet in some cases less than 24 hours later have had the code cracked. Apple, Blizzard, Sony, etc have all made said claims and have been proven wrong. 

 

I want to know how salt works, how the code works, how the server knows how to make it work.  The reason I want to know is simple, from one computer to another salt has to be uniform in its results and its ability, if not then only one computer in the world would be able to use salt correctly.

 

The reason I say that is when you input a database that was encoded with salt from one server to another it still works... so there is a uniform functionality there somewhere.

 

I'd like to know why people think salt is the end all say all? How the SHA, MD5, and Salt securities work, and if it is impossible to crack how long do you think it is going to take till it is, because we were told the same thing with MD5 weren't we?

I think this may help you out, Matt.  SHA1 and MD5 are one way hash functions.  Meaning, no one has been able to take an MD5 string, throw it through an algorithm they made, and get the clear text.  At least not that I know of.  However.  Some people have a database of words and their corresponding MD5 string.  They simply iterate through a dictionary, store the clear text and then the hash of the clear text.  So, once they steal all your user's passwords hashed with MD5, they can simply look in their database to see if there are any matches.  It's called a reverse lookup.

 

http://www.md5rainbow.com/

 

That is at least partly why having salt is important.  Because these common reverse lookups won't work.

 

 

Alright, some numbered questions:

 

1)  Avoiding leaking server details:

 

Your production server should have errors off entirely, only logging them to a file that's not readable by the public.  Errors all the way ON in your dev environment, OFF in your production environment.  Do not ever dump SQL, usernames, or file locations to the screen.  That's why error pages are so infuriatingly vague.  "Oops" gives an attacker no information.

 

2)  Input filtering.

 

You probably got confused at the line:

if (!preg_match('/^[a-zA-Z0-9_]{1,60}$/', $user))

preg_match is a PHP function that parses regular expressions.  Regular expressions are their own language (compatible with perl, the unix command line, and many other languages) and they're pretty difficult to understand.  This particular preg_match will return if the username is between 1 and 60 characters, and it only allows letters, numbers, and the underscore character. 

 

3)  The source of pwqcheck:

 

This is too difficult to do line by line.  It appears to be writing commands to the unix command line though...which is pretty stupid.  It requires the pwqcheck program to be installed and configured.  It doesn't appear to actually sanitize the password though.  I wouldn't use a command-line library for password validation.  This is the perfect spot for a regex.

 

I assume you understand why echo does what it does, and that was just an example....

 

4)  A "salt" is a random string that's known only to your code, which you stick onto one end of the password or the other (or in the middle, whatever) to increase the complexity of the string and to make the hash less susceptible to rainbow tables.  While your users may use the password "fluffy," if you include a salt to make the salted string "fluffy*nuc49nc*$&*Th" then that string is far less likely to appear in a rainbow table.  See?

 

Sha/md5/hash, after the plaintext password has been salted, are used to one-way hash the resulting salted password so that the resulting value is not reverse-engineered. 

 

So to summarize:  A salt is a string you add to a plaintext password to make the resulting hash (using a hash method like md5, sha, or crypt) MORE secure.  Salting is not a hashing method.

 

Every salt is eventually crackable, but the methods they use to generate the hashes are so complex that they cannot be reverse-engineered mathematically.  You can only crack them using brute force.  Salting slows the brute force process.

 

Everything is always crackable.  Even SSL is crackable, and with the advent of quantum computers coming (fingers crossed) in the next 15 years, we'll see instant cracks for the most complex cyphers.  We'll have to completely re-work security when we start doing quantum computation.

 

Sony
Sony stores their passwords in plaintext.  Simply declaring that you're secure doesn't do anything unless you're actually secure.  Look at Valve for a good example.  Valve's servers were compromised and their database stolen.  However, the one-way salted and hashed passwords cannot be retrieved even by the person who has possession of the database. 

 

The inner workings of the actual hashing functions are too complex for me to handle here.  You can look up videos and explanations of how each individual hash function does its thing.  It's extremely complex, there's a lot of math involved, and it's really hot all that interesting, even to math/cryptography nerds like me. 

 

 

Poor form? I was a retort to your snide teacher metaphor. I'm with ManiacDan though - I don't see a need to continue name calling.

 

That post says you're not ready for PHP security yet. You have a lot to learn about the language before you start producing scripts to interact and store sensitive data such as passwords. The article has been 'dumbed' down so average developers like us can easily understand this complex topic. If you don't understand it, sorry to say, you aren't ready to implement it.

 

To cover your questions

1. There are many ways to do this. A debug flag/constant is the most popular method, from what I've seen. In your error handling function, you check for this flag. If it's set to true, you output data sensitive to your system. If it's set to false, you only output a generic error message, and probably write the specifics of it to a log file not accessible to the outside world.

 

2. The input filtering section has a total of 6 lines of code. It uses 4 functions, one of which we've defined ourselves. The other 3 are very straightforward and explained in the manual. preg_match() involves Regular Expressions, which is an entirely different topic.

 

3. Password policies can be extremely complex. This isn't a beginner topic. The script that they use is so complex they have yet to implement a pure-PHP solution, and instead direct you to using an outside application they've developed. That entire function is simply interacting with an external application.

 

Your last comment gives me the idea that you simply skimmed through the article. They specifically go into MD5, how it was 'broken,' and how it doesn't really relate to hashing a password. The rest of it tells me you don't understand as much as you think you do. I think your first step should be putting aside this predisposition that you know what you're dealing with, and soak up everything. You've made assumptions that are misinformed, and some, completely wrong.

 

We use one-way algorithms because they are just that. One way. They don't get 'reversed,' they get brute forced. SHA and MD5 are bad not because they can be 'cracked' (incorrect terminology aside), but because they were built for speed. When the only way to attack your hash is through brute force, speed is your enemy. We use salts to prevent simple passwords from being brute forced nearly instantly. We use random salts to prevent an attacker from being able to apply a single brute force attack to every hash.

 

I'm done with this thread though. You seem have already come to conclusions on subjects you know very little about. That's not the type of person I enjoy helping. Best of luck :)

@ ManiacDan - It's my understanding that salts should not be considered secret. They're only there to add entropy to a password, and to require a unique brute-force attack for each hash. Should they be given out publicly? Probably not - but they are stored in plain text, so they aren't really 'secret.'

 

If there's a specific hash someone wants to attack, a salt isn't enough. This is where the concept of key stretching comes in. An attacker calculating hundreds of billions of hashes a second isn't intimidated by a long, complex string. Slow this down to hundreds of millions a second, and the long, complex string becomes much more of an issue.

 

Please correct me if I'm wrong. This is only me interpreting what I've read on the subject.

What are your (both xyph and Dan) thoughts about using a timestamp as a salt?  It has the following benefits:

 

Always unique per user.

Fairly randomized on its own.

Fairly long.

Difficult to guess as it can look like benign user profile data (it doesn't need to be labeled as a dedicated salt column, although obfuscation is admittedly a weak benefit).

@ ManiacDan - It's my understanding that salts should not be considered secret. They're only there to add entropy to a password, and to require a unique brute-force attack for each hash. Should they be given out publicly? Probably not - but they are stored in plain text, so they aren't really 'secret.'

 

If there's a specific hash someone wants to attack, a salt isn't enough. This is where the concept of key stretching comes in. An attacker calculating hundreds of billions of hashes a second isn't intimidated by a long, complex string. Slow this down to hundreds of millions a second, and the long, complex string becomes much more of an issue.

 

Please correct me if I'm wrong. This is only me interpreting what I've read on the subject.

"Known only to your code" means "don't make it your domain name or put it on a post-it."  What with it being a bare word in your code (or a config file), it can't actually be a secret in the strictest sense of that word.

 

As for key stretching, that's exactly why that was developed.  Cryptography is a constant war.  First we had md5.  That wasn't computationally complex enough, so we came up with sha.  Then rainbow tables became relatively easy to use, so we added salting.  GPUs were involved in password cracking, so we couldn't even do that anymore, so we went to key stretching and better hash functions.  The war will continue forever. 

 

(Disclaimer:  Not an accurate representation of an actual timeline, don't use this for research papers or cite it during an argument).

 

-Dan

The bottom line is that salting will prevent anyone from brute forcing the password if they do not know what the salting is. Which is also why the salt should be unique per user. If the system is public, a cracker would almost more than likely create their own password in the system. Then if they were to get ahold of the database (and not the logic for salting) they could run some trial and error on the hash of their own password to try and figure out the salt. If they figure out the salt for their password using values only in the database, then they can determine the salts for all the users.

 

So, it's not a bad idea to have a little salt and pepper (pun intended) whereby you use a variable value from each user (e.g. timestamp of when they signed up) AND a static (or semi-static) value that is determined in the code. One of the early examples in this thread was to use modulus on a value to determine the hashing method. Although not strictly a salt, it adds a level of variability that someone with access to only the database would not easily know. But, you could just as easily use something such as a math function against the timestamp or anything so that the hacker could not easily determine the salt from just the database. I'll sometimes use strrev() on the password in addition to the salt.

 

If a hacker gets both the database and the logic then all bets are off. They can, with sufficient time and resources brute force any of the hashes. Which is why string-lengthening is important.

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.