Code Tips

Why Salt Your Hashes?

Note: Post has been updated below

SaltSalted hashes? Have I decided to blog about breakfast?

No. By “Hash”, I mean “cryptographic hashes” and by “Salt”, I mean “additional input added to a one way hashing function”. Back in Episode 4 of my Podcast, I talked about a system that was written from the ground up to manage users, passwords, and permissions. During my little rant, I talk about storing passwords as the result of a one-way hashed value, but I didn’t really elaborate.

I realize that many of my regular readers may know this information, but I’ve been surprised at how many that I’ve found who do not. Hopefully, I can shed some light to those who don’t know and also become a viable source in search engine results for when the question is asked.

Let’s get the easy part out of the way first. We KNOW not to store plain text passwords, right? Some people know that and choose instead to store the passwords via two-way cryptography, meaning they can encrypt and then decrypt the password to compare it or email it you. That is also a terrible idea. Now, your entire system is only as secure as the security around your decryption key or decryption certificate. You’ve just made an attacker’s job very easy.

The better way to store passwords is to only store the result of a one-way hash. Then, when someone presents their password for authentication, you just hash the input and compare that to what you have stored in the database. However, even though this is good, it is still not right.

Take this for instance. Here is a sample table with hashed passwords.

user password
pete b68fe43f0d1a0d7aef123722670be50268e15365401c442f8806ef83b612976b
bill 59dea5f67aea4662c26a5ac6452233e783407d55c4f96d6c4df6f0d7c06c58af
jeff b68fe43f0d1a0d7aef123722670be50268e15365401c442f8806ef83b612976b
andy b6642c42bd670b0c070dd45d087877a4bc8d6ee29c88df59273ea48ed72b76c4
ron b68fe43f0d1a0d7aef123722670be50268e15365401c442f8806ef83b612976b

Right away, you should be able to see a problem. The hashes for pete, jeff, and ron are all the same. A common attack against hashed passwords is a rainbow table. In that case, dictionary words (or common known phrases) are pre-hashed and those hashes can then be compared against a compromised database. Let’s take a look.

password SHA-3 (256) Value
password b68fe43f0d1a0d7aef123722670be50268e15365401c442f8806ef83b612976b
letmein ceaa5fd0a764ad8202f43f2efc860d8c7472911ca9d1ccea2dc232713ae1fc0d
blink182 aadfce5bdba224673c168fb861f45cdd6ebf4e34d35001ae933bd53b7f6b337f
password1 abbe6325ea0d23629e7199100ba1e9ba2278c0a33a9c4bfc6cd091e5a2608f1a

Now, by comparing, we can see that the password for pete is the word password. That means that the password for jeff and ron are also “password”. By only cracking one hash, we gain access to two other accounts. This is not good.

The fix is to “salt” the password before hashing it. You want that salt to be a unique value. Some people create a random value and then store the salt alongside the password in another database column. Others derive the salt from something like the row’s primary key, etc. Either way is fine (as long as your derived value won’t change).

Now, let’s examine our user table.

user salt password
pete I7Yrs9THQyLxpVllSwbf 9b7ec6d82075a9e7d8227897e8919785031b9a7cdab5750dea044390d1fd1f46
bill K0kJJCQcVVqfLzykcpbP 297d00ae29ff3c32fe874c00d0154085ac862a154b061c17cd465de7f1cdee9a
jeff NwV7PdmPUKY6GgScEUqu c2936d36583d0513980e496005872e4954d142ed823b7b0b1abf28211efc538f
andy GpHrXjbQRTjObZWM7jbd 0338bd60f7d761ce9c8922087e87c9ccb7936bb5f9c5c28d72fd28f4d8708e6b
ron iHh8SX7fQEF2WFUOfxEp 07f459276c9be7d63aa8d57dac7468c8b16dd4367e91615fb9972543a707c403

We notice right away that none of the user’s hashes are the same. I didn’t change the passwords, but the salt values made the passwords unique so that they all hashed differently. We can no longer tell whose passwords are identical. Also, our plain dictionary attack no longer works. Even though we’ve telegraphed to the attacker what salt to use, the attacker would have to generate rainbow tables across their entire dictionary for each individual salt.

This isn’t 100% secure (nothing is), but this is a best practice and certainly will slow the attackers down. This method of storage, combined with strong passwords should keep your data as safe as it can be.

Thoughts? Disagreements? Share them in the comments section below.

EDIT (5/16/2014): I talked on my podcast referenced above about how easy it is to get behind or to overlook things if you do your own security as yet another reason NOT to do it. I recommended just using existing products or frameworks that have already been hardened over rolling your own. As a perfect example, I talked about doing all of this, but forgot about bcrypt (and others) that are much more secure, salt the value for you, and already have libraries in all of the major languages.

Mentoring

Podcast Episode 14 – Mentoring

MentorEpisode 14 of the Pete on Software Podcast is out and this week, I’m sharing my thoughts on mentoring. The word mentor has been watered down to just mean people that you want to look up to and emulate. To me, a mentor relationship is a two way street and unless you are having personal interactions with your “mentor” on a regular basis, you’re doing it wrong.

To top it off, when looking to find potential mentors, we may be barking up the wrong tree in terms of finding what we really need. I don’t spend any time talking about why you need a mentor, because I felt that everyone knows why they need to have their own Yoda or Mr. Miyagi.

You can also subscribe to the podcast at any of these places:
iTunes Link RSS Feed

Thanks to all the people who listen, and a special thanks to those who have rated me. I really appreciate it.

The episodes have been archived. Click Here to see the archive page.

Dumb Mistakes

iOS – TableView Row Height Wrong on 64-bit Only

I had a fun little problem pop up at my client site today. We had a tableview that was displaying data that looked perfect when running on everything except for an iPhone 5s. After a little bit of DuckDuckGo-ing, we came across these Stack Overflow questions here and here that suggested that the heightForRowAtIndexPath method might be the culprit.

When I went and dug in, I found this warning (I did do some cut and paste to get the warning just over near the code):

float to CGFloat Warning

If you can’t read it, that warning says, “Conflicting return type in implementation of ‘tableView:heightForRowAtIndexPath:’: ‘CGFloat’ (aka ‘double’) vs ‘float'”

The code was the following:

- (float) tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (indexPath.row % 2 == 0) {
        return 247.0;
    }
    else {
        return 315.0;
    }
}

The signature for that method means that the code should have looked like this:

- (CGFloat) tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (indexPath.row % 2 == 0) {
        return 247.0;
    }
    else {
        return 315.0;
    }
}

So what is the explanation? Basically CGFloat was typedef’ed as float. However, Apple wanted you to use CGFloat in case they ever changed what a CGFloat was going to stand for. Apparently, with the move to 64-bit, Apple has done just that. In 32 bit versions, the signatures were identical. However, now in 64-bit land, because the method was returning the wrong type, iOS considered the return value to be 0, breaking our layout. By only changing the return type in the signature to the proper value, the app functioned again properly.

Keep this in mind the next time you might think about being smarter than the language designers and consider not using their typedefs.

Podcasts

Podcast Episode 13 – Itzik Ben-Gan on T-SQL

Itzik Ben-GanIn this week’s episode, I interviewed Itzik Ben-Gan. This was a huge treat for me because Itzik is someone that I’ve learned a lot from and looked up to for almost a decade. This wasn’t even an interview that I would have chased down on my own, but I will say that doing the interview has given me confidence to chase down some others.

If I didn’t land this interview for myself, then who did? Jeff Meyer (another Itzik fan) reached out to Mr. Ben-Gan on my behalf and got him to agree to come on the show and then looped me in to make the necessary appointments. All along the way, I was a little nervous about talking with Itzik. You know what they say about meeting your heroes…

In this case, that fear was totally unfounded. Itzik was amazingly nice and right off the bat, I could tell that he was exactly how I had hoped that he’d be. The guy just KNOWS T-SQL. We had a great conversation about T-SQL features: those that are underused, those that are powerful, and those that aren’t there yet – but should be. We also talked about his teaching and writing style and along the way collected some great resources.

Even if you aren’t a developer, you should listen to this week’s podcast. It is a pleasure to listen to a passionate expert talk about their craft.

You can also subscribe to the podcast at any of these places:
iTunes Link RSS Feed

Thanks to all the people who listen, and a special thanks to those who have rated me. I really appreciate it.

The episodes have been archived. Click Here to see the archive page.

Conferences

Stir Trek 2014 Talk Recap

Stir Trek LogoI did it! Mission Accomplished (and I don’t mean in that ironic “banner on an aircraft carrier” way).

A few months ago, I submitted a talk to Stir Trek and it got accepted. I had wanted to speak at a conference again, but I was super stumped as to what to talk about that would be interesting enough to stand out. There were only 40 speaking slots and hundreds of applicants, so it had to be good. Part of the selection this year was done blind (based on nameless abstracts), so content really needed to be key.

Thankfully, my co-worker Jey came up with a great idea. He suggested talking about how to do push notifications in iOS. I wanted to really think big, so I expanded it to include Android. Another co-worker, Jeff, thought that if I included Win Phone 8 I would really increase my appeal. So, I submitted this:

Don’t Call Us, We’ll Call You: Push Notifications in iOS, Android, and Win Phone 8

Mobile is the future and one-way-only conversations are boring. Find out how to keep your app’s users in the know with push notifications. In this session, we will evaluate the push notification landscape, see why push notifications are useful, and how you would send and receive them to iOS, Android, and Windows Phone 8 devices. Then, we’ll take a look at writing a push server, and evaluate the pros and cons of rolling our own versus leveraging a Notification as a Service platform such as Urban Airship or Parse.

As I mentioned in my talk, my original idea was that writing the native push servers would be a really bad experience and then the cloud providers would wipe all of my tears away. Nothing could have been further from the truth. I mean, the native push servers (especially iOS) definitely had their challenges, but once you write them, they are done. The cloud providers don’t protect you from the worst parts of setting up the push servers, anyway. Their benefits aren’t ease of development, but rather their reliability and extra features that they offer that don’t show up in a simple push demonstration.

Preparing for the talk was a lot more difficult that I originally thought and took at least twice as long. I wrote an iOS application, an Android application, a Windows Phone 8 application, and a .Net REST service to push to them. I deployed the .Net service to an EC2 instance so that it would be available everywhere.

The code to make the application do what it needed to do at its core wasn’t difficult (on purpose). However, the amount of yak shaving that I had to do to get things rolling in iOS, configure the EC2 instance, and get the Windows Phone 8 environment running inside VMWare were really painful.

I did learn a lot, though. Thankfully, all of my demos went off without a hitch. That was my biggest fear, but I was very fortunate to have had no problems at all. My next biggest fear was that I’d get questions that I had no idea about. Fortunately, I got great questions from the audience and I was able to speak to them with some degree of intelligence.

I had a lot of friends turn out to see me talk, which helped a lot. It was also an amazing experience to present on such a huge screen and in such a large room. Add to that the way that the speakers were treated by the amazing organizers (see our speaker room spread here), and it served to make the entire day very special for me.

As promised, all of my code and slides are up on the Stir Trek Github Repo under the Mobile track, so check them out.

If you were at my talk and would be so kind as to rate the talk (and give any optional feedback), I’d really appreciate it. You can do that here.