4

I am currently working on a Form Application in C# that has a login system where users must input their username and password to use the program. These user accounts are stored in an XML file and are currently stored in plain text (I am only in the prototype stage). I am looking for a way to hash the passwords (and maybe the usernames) then store them in the XML file.

I have already done some research into this, but every time I do another search, I find a different way of encrypting a sting. Some ways were able to encrypt and decrypt the string while others are only able to encrypt the string. I am trying to find what will work best for my situation.

For my code, I only need to hash the passwords. This will help keep them more secure to my understanding. I can apparently just hash the password on login and then compare so decrypting isn't a real issue. Also, the process needs to work on any computer. I've seen some answers which only work on a single machine, I am looking for something that is cross-machine compatible if possible. Another thing is, the output of the hashing must be able to be serialized to an XML file without much reworking of the code used to write to the XML file. Currently I am using an XMLSerializer and a StreamWriter to write to the XML file.

Again, I've seen many ways to encrypt or hash a password but I am relatively new to encrypting and hashing stuff so I do not know a good way to do this. Any help will be greatly appreciated and if need be I can add some sample code.

Josh H
  • 63
  • 1
  • 8
  • Keyword is not encrypting. Instead, *Hashing* – EZI Feb 18 '15 at 15:02
  • I'm guessing there must be some form of client/server communication here, but you've not clarified that. If there *isn't* (and this just a local application login) then hashing is pointless. If the password *is* going over a network, then storing a client side hash may be nice, but storing a server side hash (maybe in addition to client side hash) is the best practice approach. – PaulG Feb 18 '15 at 16:36
  • There will be client/server communications in future versions. Currently it is just a client and everything is stored locally. Once the server is created, everything with the login will be handled server side (including storage) – Josh H Feb 18 '15 at 19:32
  • possible duplicate of [How to hash a password](http://stackoverflow.com/questions/4181198/how-to-hash-a-password) (note this answer http://stackoverflow.com/a/10402129/1185053) – dav_i Feb 19 '15 at 10:29

3 Answers3

4
  1. You should generate random string called "salt"
  2. Combine your plain password string with salt and hash result

IN DETAILS:

  1. Generate a long random salt. Note: salt must be different for every login-pass pair!
  2. hash = sha(salt + password) //pseudocode
  3. Save hash and salt in your file

When login:

  1. Calculate hash again. hash = sha(salt_in_file + password_input)
  2. Compare hash with your hash_in_file

And don't use MD5! Better look here Also look through this article

UPDATE: Ok, maybe this approach is not good enough. If you want really strong security you should use special slow hashing algorithm. Some of them already maintain salt. I don't claim to be specialist in cryptography. Never rely on single opinion in this area.

Anyway, the above should be enough in many cases.

Community
  • 1
  • 1
shameleo
  • 344
  • 2
  • 13
  • 1
    Sorry to say, but this is **not** what you should do. Algorithms like SHA* and MD5 are not appropriate to hash passwords, because they are designed to be fast, and therefore can be brute-forced too easily. Instead one should use a hash algorithm with a cost factor like BCrypt or PBKDF2. – martinstoeckli Feb 19 '15 at 12:04
4

Proper way to hash a password is to use a specialized function like bcrypt or scrypt.

DarkWanderer
  • 8,739
  • 1
  • 25
  • 56
2

Fast hash algorithms like MD5, SHA-1 or even SHA-256 are not good choices to hash passwords, because they are much too fast and can be brute-forced too easily. One can calculate about 3 Giga SHA-1 per second with common hardware.

Instead you can use a slow key-derivation function like BCrypt or PBKDF2. CSharp has native support for PBKDF2, it can be implemented with the Rfc2898DeriveBytes class, an example you can find here.

Also easy to use is this BCrypt library. Often people are not sure if it is safe to use such libraries, but i don't think there are arguments against using it. As long as the library returns the correct value and generates the salt correctly, it should be fine, because the security comes from the algorithm and not from the implementation.

martinstoeckli
  • 23,430
  • 6
  • 56
  • 87