6

I work for an online shop and since I worked here we have stored customer passwords in plaintext. I joined the company as a data inputter and when I discovered that we did this I flagged it up with management but they didn't seem interested or concerned. Several years later I am in charge of the website and I now want to encrypt all our customer's passwords.

What is the quickest and easiest way of encrypting all customer passwords on a .NET ecommerce website? Are there .NET libraries we can make use of?

Edit

I currently know next to nothing about encryption or password security. I have been accused of doing no research before posting this question. I have actually begun researching this topic today and this question is part of my research. I'm sorry if people are offended with my lack of knowledge but it isn't through laziness. I simply don't know anything about this field and I am now trying to find out. This question is part of that. I would really appreciate any help you can give me.

Mike
  • 77
  • 3
  • 4
    You want to use a password hash (like PBKDF2), not encryption. Rfc2898DeriveBytes in .net. Use a per user salt and at least 10000 iterations. – CodesInChaos Jan 16 '15 at 13:16
  • 7
    I'm not the downvoter, but it is obvious that you haven't done any research at all before asking or you wouldn't be talking about "encrypting" passwords. – Bob Brown Jan 16 '15 at 13:17
  • 2
    Read this post about passwords. – Lawtonfogle Jan 16 '15 at 14:49
  • Also remember when you get round to encrypting all the passwords, you will need to update the login/register and any other user related code to implement the hashing choice you make. – Ryan McDonough Jan 16 '15 at 15:18
  • Take a look at this answer. It has a nice in depth description of each step used for password hashing and why you shouldn't roll your own. Rely on a pre-existing implementation (written by experts) – dberm22 Jan 16 '15 at 15:27
  • I agree that in this case hashing is the superior choice compared to encryption, but you always have to check that you don't need the password for challenge response schemes like CHAP. They don't work with hashed password (or are cheating like MS-CHAP where the password hash is as good for logging in as the password itself). – Drunix Jan 16 '15 at 18:01
  • Didn't see this mentioned anywhere. But you may want to consider forcing user password resets. Can you be sure that the plain text passwords aren't already exposed somewhere? Or do you have data backups that will have these plain text passwords? It's a risk to customer experience I know, but not nearly as big as having their password stolen. – CLo Jan 16 '15 at 18:37

3 Answers3

5

Passwords should be salted and hashed, not encrypted. You should use a slow hash to mitigate precomputation attacks. There is .NET code here: https://crackstation.net/hashing-security.htm

Edited to add: If your number of accounts is low, you might be able to simply block login attempts while the hashing code runs. However, it's designed to be slow, so you may have to allow logins while passwords are being hashed. That's no problem. Compare the plaintext password first; if there's no match, hash the offered password and compare again.

Do not forget that you have to store the salt as well as the hash. If you're not changing your database schema, those can be concatenated and stored in the existing password field, assuming it's varchar. Otherwise, you may have to add columns to the database and clear the plaintext column after the hash computation is complete and committed.

Check your password recovery mechanism. When you've done this, you won't be able to tell users what their passwords are. You'll need some other recovery mechanism.

Not relevant to the question, but if you're not using TLS for the login, you need to.

Bob Brown
  • 5,323
  • 1
  • 20
  • 29
  • Not exactly the best implementation. 1) It's using a hash size of 24 bytes, increasing the hashing cost for the defender by a factor 2 without costing the attacker anything. 2) 1000 iterations is very low. 3) The 24 byte salt size is silly but harmless. – CodesInChaos Jan 16 '15 at 13:33
  • @CodesInChaos: Both are constants defined in the code, and so easy to change. There is an extensive essay describing how to select appropriate values for a given application. – Bob Brown Jan 16 '15 at 13:37
  • 1
    @CodesInChaos: I should add, in defense of your own comment, that it is foolhardy to do cut-and-paste programming of crypto applications, including hashing, without understanding what's going on. That's why I linked to the long essay instead of something else. – Bob Brown Jan 16 '15 at 13:43
  • Safe defaults are important. 2) Outputting 24 bytes from PBKDF2-HMAC-SHA1 for a login hash cannot be justified. It's simply a bad choice.
  • – CodesInChaos Jan 16 '15 at 13:46
  • 2
    @CodesInChaos: Consider communicating your remark to Taylor Hornby. He is quite open to fixing things on that page. – Bob Brown Jan 16 '15 at 13:51
  • @BobBrown, if it's easy to change, their examples should be more correct. The PHP is fine, SHA-256 has a native 32 byte size. The Javascript is wrong, SHA-1 has a native 20 byte size. The C# is wrong, SHA-1 again. The Ruby is also wrong, SHA-1 again. SHA-1 should be capped at 20 bytes. I'd bump up the iteration count dramatically, and even more for the SHA-1 examples. I would also note that I have collected a variety of examples of PBKDF2 with test vectors at my github page if you'd like to benchmark some against each other. – Anti-weakpasswords Jan 17 '15 at 03:38