I want to encrypt passwords using the C# WPF. what is the best algorithm (and easy to implement) to use? and I want some example about how to use it ...
Do not try to create your own encryption algorithm rather use the cryptography classes provided in the .NET Framework through System.Security.Cryptography.
For passwords a good solution is to use a oneway encryption like a MD5 hash or SHA1. And when the user enters his/her password you compute the hash and compare it to the stored hash. The advantage of this is that you do not need to worry about how to securely store the key used to encrypt the passwords.
To increase the security of using a one way hash you can apply a salt, this help restrict the effectiveness of certain types of attackes like a dictionary attack etc. I have not read the wiki entry, but I am sure this will provide more detail.
Related
I have a C# application in which I sometimes have to encrypt some data (XML file). Basically, the problem is I cannot store any keys on a server, or directly in the code, as .NET apps can be easily disassembled with for example dotPeek.
So basically my app would encrypt XML file and save it on disk, and then would be able to decrypt it.
I came up with an idea to ask for a passphrase every time a user wants to encrypt/decrypt the data. This passphrase would be hashed with SHA512 and the resulting bytes would be used as a key to encrypt the data. Then if the user wants to decrypt the file, they are asked for a passphrase again and this passphrase is used to decrypt the file (it may fail if the user enters a wrong passphrase).
So my first question would be: Is it actually a good idea?
My second question is about the implementation. I have hashing, serialization, deserialization, but I don't know which encryption algorithm should I use (I guess not RSA as the data to be encrypted would be really long) and then can I pass the passphrase as a key to this algorithm?
You've stumbled upon the idea of a Key Derivation Function (KDF). What you're suggesting is, with a few differences, an excellent idea and one used often. The small-ish issue is that SHA-512 alone is not a good KDF. I recommend you read about PBKDF2 (in .NET, the implementation is called Rfc2898DeriveBytes). Password hashes like bcrypt and argon2 are also very viable choices.
In regards to your question regarding the encryption algorithm, AES is currently considered the "standard" symmetric encryption algorithm. There are many other viable options however. Just ensure you aren't using DES or Triple-DES, they're dated algorithms. Also ensure you're using a secure block mode. GCM is arguably the "best".
I am new to asp.net mvc language. I see this code using System.Security.Cryptography; for what I have search in Google it is for making a salt + hash passwords.
My question is can it be decode using c#?.
You would be correct in saying that.
The short answer is no. Hashing provides a 1-way interface for obscuring data where as encryption provides a 2-way interface for the encryption of data / decryption of encrypted data.
The only way an hash cant be 'decrypted' and I use that term loosely is by brute forcing via the hashing method. This is done by running a bunch of password and salt combinations through the same hashing method until a match is found to the original hash. However with a strong hashing method and password + salt this can become an almost impossible task.
Helpful Discussion: Fundamental difference between Hashing and Encryption algorithms
EDIT:
The link of the online cryptographer you provided uses what is known as a Symmetric-key algorithm. This means that a single key is used for the encryption and decryption of the data.
https://en.wikipedia.org/wiki/Symmetric-key_algorithm
Short answer: no.
See also https://en.wikipedia.org/wiki/Hash_function
Correctly salted hashes cannot be reverted, which is the point of doing that.
No. Not easily.
A Hash will take some text and produce a number ( usually )
eg, a md5 hash
password => 5f4dcc3b5aa765d61d8327deb882cf99
By the nature of the hash, there is no easy way to get back from the number to the original text "password"
But, for the semi clever hacker, you can generate hashes using a dictionary of all words and in reasonable time crack most hashed passwords because people use common combinations of words and symbols. So if you happen to get a list of hashed passwords you can run a dictionary attack on them. Anyone who uses "password" as their password will end up having the same hash.
So as a defense to that, if you add some text unique to each user, a Salt, say, your username, now you've made it harder :-
your string to hash becomes "Yukkipassword" which hashes to 52fbd06f5b93a51b3f3cd9e807a9f61c
Now everyone who uses "password" for their passsword will also have a different hash, and it becomes really difficult to dictionary attack the password
I am currently thinking of something to do as my final project for my C# class. The thing that came up to my mind was a password-protected data storing application which would require a password to access data stored in a binary file.
The problem is that I am not sure which encryption to use if I would decide to do this project.
What encryption would fit best this scenario? Which encryption is the best?
Just little more info what I have planned.
First, user must specify the user name/password information to save the data. Data would be saved in binary file which later should be able to view after login information are correct.
I think you should go with AES in CTR mode.
A C# implementation of Rijndael (the underlying cipher of AES) can be found here.
There is probably not such a thing as the best encryption algorithm, but it is what everybody else is using right know.
To clarify further:
This is how encryption works:
Plaintext -> [encryption] -> Ciphertext -> [decryption] -> Plaintext
This is what you would have to use for a password manager.
This is how hashing works:
Message -> [hashing] -> Hash -> [???] -> Message
You can (and should) use hashing algorithms to store (hashed) passwords in a database for authentication purposes (e.g. log into a website). To do so, you use a salt or a key-based message authentication code.
Instead of "dehashing" the hash stored in the database, you just hash the user input and verify if it matches. This does not work for an application like a password manager.
With a cryptographically secure hashing function (like SHA-512), it is currently impossible to "dehash", i.e., even if you know the hash, you cannot retrieve the message.
Not sure if this is an answer to your question, but alot of systems that store usernames and passwords tend to just hash the passwords, so you never actually store the users password, just the one way hashed version of it. That way when they try to login again you just hash the password and compare it to the existing one.
MD5 is the simplest one, but I believe SHA256/512 is one of the better ones to use, this is a one way hashing algorithm though, and may not be applicable to your situation if you need to be able to ever gain access to the plain text version of their passwords. Usually this isnt an issue as you can just get them to change their passwords and a user never really needs to see their password in plain text.
If you cannot use one way hashing, then just use blowfish or some other simple two way encryption algorithm. The internet is full of different .net encryption providers. If it is homework I dont think it will really matter, as long as you can show a working knowledge of why and when you would use encryption you should get marks.
We are storing hashed passwords in a database table.
We prepend each password with a random salt value and hash using MD5CryptoServiceProvider.
Is this safe? I have heard MD5 was "broken".
If not, can you recommend an alternate hash method to use (specific .NET framework class)?
The security of a hash function mainly comes from the length of its output (message digest): a longer digest gives greater collision resistance. The birthday paradox tells us that on average you'd expect to find a collision from a work function of the square root of the digest size: in other words, given a 128-bit digest, an attacker would expect to hit paydirt after 2^64 trials.
MD5 has been frowned upon by the cryptographic community for some years now because it only has a 128-bit digest, and there are also some interesting cryptanalytic results which might effectively reduce its strength. SHA1 (160 bit digest) had been the preferred alternative, but even then it is starting to look like it was not long enough for a well-motivated adversary and there are also some interesting results in the research community. The SHA-2 family (output sizes from 224 to 512 bits) are the current preferred hash functions in widespread use. There is an active research competition organised by NIST to find a successor for SHA-2, but we won't have a new standard until 2012 or so.
Now, in the specific case of storing passwords, I note you are using a salt. This is the strongly recommended practice; without a salt you would be vulnerable to a rainbow table attack. I believe that this leaves you with only the brute force attack to consider; this is where keylength.com comes in. It brings together recommendations for key and digest sizes from across the cryptographic community and gives expected security timescales for various algorithms, considering current computing power and taking Moore's Law into account. Consider what sort of assets you are protecting and how long you need to a password to remain secure for (do you have an enforced password change policy, for example?) and that should pretty much answer the question of the digest size you need.
Of course, the best password storage in the world won't help you if your users use easy-to-guess passwords. Do you provide your users with tips for strong passwords? Have you considered a password strength meter or similar?
I think SHA256, SHA512 are more safe at this moment :)
See wiki
No, you shouldn't be using MD5. But you shouldn't be using a single round of any general purpose hash function, no matter how cryptographically secure it is, either! Not MD5, not SHA-1, not SHA-2, not SHA-3.
Why? Because general purpose hash functions are designed to be fast. And fast is exactly what you don't want in a password hash. Fast means that when the bad guys get your database, they can run a plain old dictionary attack against it in a reasonable amount of time.
What you need is slow. The simplest way to be slow is to iterate the fast hash function thousands of times - that's what the MD5 and SHA-1 based password scheme used to store passwords on UNIX-like systems do (it's not just one round of MD5 or SHA-1). Another way is to use a cryptographic primitive that is designed to be slow - that's what the "bcrypt" password scheme does.
This Matasano article, What You Need To Know About Secure Password Schemes, has some good reading on exactly this subject.
With a salt MD5 is much more secure than without, but you're better off using one of the SHA hashes such as SHA256Managed.
Storing hashed password is better since it hides the password from prying eyes of DBA's.
Also, yes, MD5 was broken, but is still used to this day. If you are concerned about MD5, rather use SHA-1 (MSDN link here). It's a hashing algorithm just like MD5 but stronger. You can have SHA-1 hashing of up to 512 bits.
Here's an example done on VB.NET (http://www.obviex.com/samples/hash.aspx).
Here's the US Department of Homeland Security stating why people should move away from MD5 (http://www.kb.cert.org/vuls/id/836068). Summary, it's "cryptograpically broken"
I'm working on an application and I need to store the users password, so I'm thinking I'll store it in the current-user class of the registry, but I also want to hash it for the obvious reason, and I've seen news items that state that SHA1 has been cracked, is there a better (uncracked) hashing algorithm available in the "standard" system or .net?
SHA1 is not encryption, it's a cryptographic hash function. And yes it has been broken, which means it's possible to generate collisions faster than a brute force method. The SHA2 family has not been broken.
But I would advise to use a custom seed per entry so that a rainbow table could not be used for trying out passwords. If you're using the SQL Membership provider the password format "Hashed" already uses a different seed for each user.
More information about seeding your hash can be found in the article What You Need To Know About Secure Password Schemes by Thomas Ptacek.
As you say in your comment, SHA1 is a hash algorithm, not encryption. It is a one-way function that, even if it is broken, does not allow the password to be retrieved.
If you want stronger hash functions that are already in .NET, look at the SHA2 family - SHA256, SHA384, SHA512. (SHA224 also exists, but isn't implemented in the System.Security.Cryptography namespace.)
The collision attacks on SHA1 are not practically exploitable yet, but you are right to be looking ahead. NIST is currently running a selection process for SHA3 in the light of these attacks, but this is a few years from completion and commercial acceptance. SHA2 on the other hand is an existing family of algorithms that are standardised by NIST and are not subject to the attacks that have been successful against MD5 and SHA1.
What you need to do is salt your passwords. Here is some actual sample code in C# that uses SHA1 and salting.
The problem with SHA1 "being cracked" is all basic possible combinations have been pre-calculated, however salting makes your password nonbasic (it is still vulnerable to a brute force if it is weak or easily guessable but it kills rainbow tables)
Hash algorithms have been showing some signs of weakness as of late, which is why NIST has offered up a hashing contest much like they had an encryption contest which crowned Rijndael as the new AES.
I personally like what MD6 has to offer, as it is being spearheaded by Ron Rivest, who has been in the cryptography space for over three decades. MD6 has been withdrawn, so I suggest some of the stronger candidates in Round 2 in my humble opinion are Keccak, Blue Midnight Wish, and Fugue.
From there, definitely use good practices such as salting.
Yes you can use SHA512, just remember how long the actual hash is. You can always add extra security by salting the hash results as well.
SHA512("The quick brown fox jumps over the lazy dog") =
07e547d9 586f6a73 f73fbac0 435ed769 51218fb7 d0c8d788 a309d785 436bbb64
2e93a252 a954f239 12547d1e 8a3b5ed6 e1bfd709 7821233f a0538f3d b854fee6
If you want to look into other Hashing algorythms, here's a short list.
5 days too late but you could try this highly secure encryption function:
uint64_t highly_secure_encrypt(char* password) {
sleep(1);
return 0;
}
No way you're getting the passwords back from that.
Now, onto serious matters. If you don't already know the answer to your question you shouldn't be designing security systems.
If you're storing the password in the current-user section of the registry then the only people who can access it (under normal circumstances) are the user and the administrator. I'd trust (somewhat) the current-user section of the registry and use the standard password hashing mechanisms that the OS provides.
Jeff Atwood's "Rainbow Hash Cracking" describes hashes and password storage at a good beginner detail, and Thomas Ptacek's "Enough With the Rainbow Tables: What You Need to Know About Secure Password Schemes" goes on to tell you why you should not try and do it yourself usually.
Choosing a good hash function is less than 1% of the battle. If an attacker can run you hash function millions of times a second then (s)he can test millions of combinations a second. What you need is a slow, tunable secure hash. That's not something that is easy to come by and SHA*, MD5, etc are designed to be bloody fast since they're meant to be used over files and chunks of files usually, where speed is king.
I'd recommend reading up more, since the answers are out there and very easy to find.