Private Keys handling

Hello !

Well, I am using user’s password as Private Key to encrypt the user’s sensitive data. Hence, the key is only known by user. I want to know/learn what is the best practice for keeping the private keys.

  1. The way I am doing it, is it fine ?

  2. Shall i store private keys in a file that is 1 level up to the public_html folder ?

  3. What are the other options for this ?

Please guide !

Thanks
ZH

HASH! HASH! HASH! HASH! HASH! HASH! HASH! HASH! HASH! HASH! HASH! HASH! HASH! HASH! HASH! HASH! HASH! HASH

You never want to encrypt passwords. The problem with encryption is that it’s a two (or more) way street, in other words, you can both encrypt a password AND decrypt it. Even the best encryption algorithms are feasibly subject to brute forcing.

Hashing on the other hand is a one way street. Once a password is hashed, it can never be recovered.

Think of the password as a piece of paper, encryption as a paper shredder and paper as my hungry stomach. If you pass the paper through the shredder, you can piece it back together through trial and error - or if you left clues on the paper (an encryption key) and someone knew the clues it would be even easier.

Hashing on the other hand is like feeding me a piece of paper. I’ll gobble it up, it’ll go through my empty stomach, get churned up, broken down by my nasty stomach acids, and pooped out. It can never be recovered, ever. However, if I ate another piece of paper in the same exact way under exactly the same circumstances my poop will come out looking exactly the same. This is how hashing works.

However, if even one molecule was off or if in my furious consumption a drop of salty sweat fell on the paper the poop would come out completely different. Hashing works in this way too. Hashing makes use of something called SALT, which is a random string of characters that get sent into the algorithm with the password, to make it even more random.

The problem with Hashes is that they are fixed length. And although the length can be of any size, the length is still fixed. This means that a table of all possible outcomes could be created for any given algorithm and a hashed password could be compared with this table. Even a SALT of one character will render a rainbow table (as they are called) completely useless.

PHP has a function called md5, and it’s really easy…you just do $hashed_password = md5($password . “R4nd0m cH4raC1er2”); and BAM! you have an impossibly irreversible password. You might be wondering…well how does a user log in!?

You store the hashed password in your now secure database. When a user logs in, you hash their password in the same way as above and compare it with the hashed password in the database. If they match then you can let them log in!

For more information, see this awesome post: http://stackoverflow.com/questions/4948322/fundamental-difference-between-hashing-and-encryption-algorithms

HASH! HASH! HASH! HASH! HASH! HASH! HASH! HASH! HASH! HASH! HASH! HASH! HASH! HASH! HASH! HASH! HASH! HASH

Which… is fine, but he didnt say he was sending the password. He said he was sending sensitive data. AKA stuff that will have to be decrypted on the other end because it needs to be readable.

OMGCarlos !

Thanks YES, I know about hash and most of the time I use that. But as StarLion picked the point, I want it to be 2 way. Say, I want to store the credit card info that will be used again for a recurring fee. Also, the administrator of the site wants to see the card info even something like --****-4545. So if we do hashing there, it can not be recovered. So these is a need of some cipher/decipher. That needs a private key. That is what I am asking about. Where to store that ?

Never store CC info. Ever. Unless you’re working for a major company that can comply with every regulation regarding storing CC info in your host country (which… 99.99999% of sites CANT), use an external service. Because if your security does get breached, you’re on the hook for potentially millions of dollars, even if your little store only sells 1.99$ items.

You should always use SSL, you should always use a hash on the key (the password should be hashed already, right?), and use the hashed value as the private key. Both sites will have to have the keys stored. As for where to store them… either in a database, or in a file not accessable through the web. There will always be a 'what if _____ gets hacked". There’s no foolproof answer.

Humm, thanks !

but suppose, I have a requirement to charge the user’s credit card recurring ? Or say user does not want to enter the CC info again and again, and wants an account created with us, so that he can download some updates / etc as and when required ? Like the Apple Store ?

Set up an account with Paypal, and have your subscribers run through that. Or any of the other billing services available on the web that allow recurring payments. They hold the CC info, so you dont have to, and with a properly set up IPN/API integration, you get all the information you need.

Hi !

Well, you are right. However, there are some situations where we need to store some sensitive information in the database. I hope that many other coders will agree to this point. What OMGCarlos suggested (HASH) seems to be the good option, but HASH should not be relied on only.

What I am doing now is that, using a SALT with the hash. So my encrypted string is like SALT+(SALT.SHA1()).

This solution worked and I hope this is ok. What would you say ? I have a complex algorithm that generates that SALT, and collect that SALT from the encrypted string.

What do you think?

Anything sensitive that you do NOT NEED TO REPRODUCE should be hashed. With a salt.
Anything that you DO need to reproduce (for display, for example) CANT be hashed. The idea of the hash is that it’s one way. It CAN be encrypted.

Passwords can be (and should be) hashed because you can hash the input using the same algorithm, and compare the resultant hashes.

What StarLion just said is key, just mind the situation.

Also, you don’t need to create a complex algorithm for Salts…in fact, it doesn’t even need to be secret! You can store them in Plaintext without a problem http://en.wikipedia.org/wiki/Rainbow_tables#Defense_against_rainbow_tables

What you could do to increase security, however, is generate a salt each time the user logs in. Rehash the password, and store both the hashed password and Salt in the database. Each time the user attempts a log in, just hash their password with the stored Salt and compare the two passwords.

To go a step further, you could rehash the password 1000x (or 100,000). This will not make the password itself more “secure”, but will increase the amount of time it takes to hash the password.