I am a bit of a newbie around Security nitty gritties and especially around Cryptography.
In the application we are building(ASP.net application built on .NET 3.5), we are currently using Databases to save our users authentication information (AD etc is not an option at this point).
The intention is to do a one way salted hash of the passwords using SHA256Managed on user creation and then validate the users using the same.
Ideally, we do not want to use any third party dll's for the hashing algorithm unless absolutely necessary to avoid any unnecessary dependencies.
Questions:-
1. Is there a better option than doing a salted one way hash?
2. Is SHA256 a reasonably reliable / secure option or should we be considering anything else?
3. Is the SHA256Managed implementation in System.Cryptography good enough in terms of it speed etc or should we be considering 3rd party alternatives to it?
Any pointers as to the approach / implementation will be helpful.
I did some research on this back in the day, and the consensus was BCrypt was one of the best ways to do a one way hash.
You can see a C# implementation here: http://derekslager.com/blog/posts/2007/10/bcrypt-dotnet-strong-password-hashing-for-dotnet-and-mono.ashx
In addition, what's nice about BCrypt is you can decide how many rounds you'd like it to go through.
So, you can make it take about 1 second to encrypt for example. For a user, that's an acceptable wait time, but for someone trying to attack you through brute force, 1 second is an eternity.
I am no security expert, so take what I say here as a grain of salt. A salt you can send in to your BCrypt method :)
In addition, here's some advice from Atwood on this: http://www.codinghorror.com/blog/2007/09/youre-probably-storing-passwords-incorrectly.html
Update:
Since answering this, NuGet has made using BCrypt much easier: http://nuget.org/packages?q=bcrypt
I can't vouch for any particular implementation there, so take a look at the code, but this should make using and integrating BCrypt much easier.
Yes, retina scan (just kidding). Storing passwords as hashes with salt is the correct way.
SHA256 is good. Obviously I don't know the type of an application you are working on, but SHA256 is good for the vast majority of projects. You can always go to a higher key length (384, 512) if required. Consult with your security architect.
SHA256Managed (we are talking .net, right?) is good. We use it in our projects.
Please also consider reading this:
http://www.obviex.com/samples/hash.aspx
Yes, there's nothing wrong with SHA256 and certainly SHA256Managed will be "fast enough" for most use cases (I'm sure you're not expecting to be validating 1000s of login requests per second, and even if you were, the rest of the site would still be dwarfing the login requests...)
But have you considered the Membership stuff that's built-in to the framework? They're already done all the hard work in terms of securely storing credentials, and implementing all the support functionality as well (such as password resets, etc)
Storing password hashes with salt it correct. However, it's easy to get even that much wrong. Sure, right now SHA256 will keep the baddies at bay, but give it a few years. Suddenly, SHA256 might not seem so secure anymore. You need to use BCrypt, a future-proof hashing algorithm.
Problem with doing just one pass of SHA256 is it is too fast and one with great hardware can generate rainbow tables for lots of salts easily...to get around this you need to perform key stretching....kI'm not going to give you a lesson on key stretching but the bcrypt implementation that people talk about performs key stretching. If you want a more modern alternative to bcrypt which uses HMACSHA256 or 512 in .NET, I recomend this API:
https://sourceforge.net/projects/pwdtknet/
Related
If let's say for example the creator of MD5. He created the MD5. So can he hack our accounts or other sites that are using this algorithm?
And not just MD5, other encryption algorithms too. How is it possible that it says it is almost impossible to hack those that are using these algorithms, they are design by human too.
Please explain
The only advantage the inventor has, is a good understanding of the algorithm. He can try to insert a backdoor or a weakness, but well known algorithms are analyzed by many independend cryptographers, and hopefully they would discover such weaknesses (intended or not).
As long as you do not have a thorough understanding of the matter yourself, you will always have to trust in other people. So the longer an algorithm withstood crypto analysis, the more likely it is that you can trust it.
The creators of cryptosystems should not be able to easily break them, because the security of a soundly designed cryptosystem should only depend on the secrecy of the keys. This is known as Kerckhoff's Prinicple.
I'm bringing this up after spending a few hours trawling through a number of posts on SO with regards to the most secure way to handle passwords in PHP/MySQL. Most answers seem to be fairly out of date, as are links that people are directed to. Many recommend md5 and sha-1.
We all know that MD5 and SHA-1 are no longer worth using due to the fact that they have been reversed, and also because there are a number of databases out there that have built up millions of md5/sha1 strings. Now, obviously you get around this with salt, which I intend to do.
I have however recently started playing around with whirlpool, which seems much more secure, and up to date. Would I be right in thinking whirlpool+salt is ample protection for passwords?
I was actually considering something like this:
<?php
$static_salt = 'some_static_salt_string_hard_coded';
$password = 'some_password_here';
$salt = 'unique_salt_generated_here';
$encoded = hash('whirlpool', $static_salt.$password.$salt);
?>
What do you think? Overkill or sensible?
This is probably good enough for most applications.
However, salts become (almost) useless if your DB is leaked -- including the static one if your configuration file is leaked too. They are a good protection against rainbow tables, but nowadays it's easier to use a bunch of GPUs to brute-force a given hash.
IMHO, currently the best solution is to use bcrypt. It's apparently supported in PHP 5.3+, and here's an example of how to use it.
This will be enough (however, there is no sense in static hardcoded salt). And, why not to use SHA256? Whirlpool is rarely used.
It's particularly meaningless to discuss the merits of particular algorithms without a much wider consideration of the threat models and specifics of implementations.
Yes, whirlpool does appear to have some advantages in terms of how effective it is as a hash, but as Nickolay says that may be deceptive and due to the fact it is less widely used. But there are other considerations too - for some purposes storing a 128 character string for each account may be an unnecessary overhead. For everyone it's a question of what the software supports (and some people might want to use the same account record to control access to different systems).
At the end of the day, it doesn't matter how sophisticated your hashing algorithm is:
given a free choice, users pick bad, guessable passwords
users will use the same password for different services
If it works for you - then great - but there is no universal solution.
This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
What's the recommended hashing algorithm to use for stored passwords?
Hello, I've recently been told that common hash functions such as SHA256 are insecure for use as a password hashing function because they are "designed to be fast"(incidentally I asked earlier for faster hashing functions over at programmers.se). So my question, what should be used for websites or other general applications?
Also, secondary question: Is SHA256 really not a good choice for hashing passwords? I kind of don't believe it, but I've heard crazier things be true.
(note: assume all other proper actions are being taken such as unique salts)
You should use bcrypt.
At the time of writing SHA256 is adequate for password protection, though it may not be in a year or so.
I'd maybe use SHA512 as I'm not too well traversed in what is really secure at the moment, and I'm not sure if anything can be really secure, with the huge increases of computing power in CPU's and GPU's.
Mike Howard's answer on the question Mark linked to is the correct best practice.
Simply using a good hash is insufficient because:
it does not protect you from rainbow table attacks. The same password will hash to the same result, every time. An attacker can compromise on the time vs. space tradeoff, pre-compute the most popular passwords and simply look up the answer. To defeat, you need to add a salt. (Mike suggests user id)
as you suggest, hashing algorithms are designed to be fast. This is sometimes desired, (such as getting the hash of a 50MB file) but in the case of passwords it not. Use a password-based key derivation function instead. It will significantly slow down an attacker, but not impact your own speed.
I've read quite a few times how I shouldn't use cryptography if I'm not an expert. Basically both Jeff and Eric tell you the same:
Cryptography is difficult, better buy the security solution from experts than doing it yourself.
I completely agree, for a start it's incredibly difficult to perceive all possible paths an scenario might take, all the possible attacks against it and against your solution... but then When should we use it?
I will face in a few months with the task of providing a security solution to a preexisting solution we have. That is, we exchange data between servers, second phase of the project is providing good security to it. Buying a third party solution will eat up the budget anyway so ... When is it good to use cryptography for a security solution? Even if you are not a TOP expert.
Edit: To clarify due to some comments.
The project is based on data transport across network locations, the current implementation allows for a security layer to be placed before transport and we can make any changes in implementation we like (assuming reasonable changes, the architecture is well design so changes should have an acceptable impact). The question revolves around this phrase from Eric Lippert:
I don’t know nearly enough about cryptography to safely design or implement a crypto-based security system.
We're not talking about reinventing the wheel, I had in mind a certain schema when I designed the system that implied secure key exchange, encryption and decryption and some other "counter measures" (man in the middle, etc) using C# .NET and the included cryptography primitives, but I'm by no means an expert in the field so when I read that, I of course start doubting myself. Am I even capable of implementing a secure system? Would it always be parts of the system that will be insecure unless I subcontract that part?
I think this blog posting (not mine!) gives some good guidelines.
Other than that there are some things you should never do unless you're an expert. This is stuff like implementing your own crypto algorithm (or your own version of a published algorithm). It's just crazy to do that yourself! (When there's CAPI, JCE, OpenSSL, ....)
Beyond that though if you're 'inventing' anything it's almost certainly wrong. In the Coding Horror post you linked to - the main mistake to my mind is that he's doing it a very low level and you just don't need to. If you were encrypting things in Java (I'm not so familiar with .NET) you could use Jasypt which uses strong default algorithms and parameters and doesn't require you to know about ECB and CBC (though, arguably, you should anyway just because...).
There is going to be a prebuilt system for just about anything you're going to want to do with crypto. If you're storing keys then theres KeyCzar, in other cases theres Jasypt. The point is if you're doing anything 'unusual' with crypto - you shouldn't be; if you're doing something not 'unusual' then you don't need to do the crypto yourself. Don't invent a new way to store keys, generate keys from passwords, verify signatures etc - it's not necessary, it's complicated and you'll almost certainly make a mistake unless you're very very careful...
So... I don't think you necessarily need to be afraid of encrypting things but be aware that if you're specifying algorithms and parameters to those algorithms directly in your code it is probably not good. There are exceptions to any rule but as in the blog post I linked above - if you type AES into your code you're doing it wrong!
The key "take-away" from the Matasano blog post is right at the end (note that TLS is a more precise name for SSL):
THOMAS PTACEK
GPG for data at rest. TLS for data in
motion.
NATE LAWSON
You can also use Guttman's cryptlib,
which has a sane API. Or Google
Keyczar. They both have really simple
interfaces, and they try to make it
hard to do the wrong thing. What we
need are fewer libraries with higher
level interfaces. But we also need
more testing for those libraries.
The rule of thumb with cryptography isn't that you shouldn't use it if you're not an expert; rather, it's that you shouldn't re-invent the wheel unless you're an expert. In other words, use existing implementations / libraries / algorithms as much as possible. For example, don't write your own cryptographic authentication algorithm, or come up with yet another way to store keys.
As for when to use it: whenever you have data that needs to be protected from having others see it. Beyond that, it comes down to which algorithms / approaches are best: SSL vs. IPsec vs. symmetric vs. PKI, etc.
Also, a word of advice: key management is often the most challenging part of any comprehensive cryptographic solution.
You have things backwards: first you must specify your actual requirements in detail ("provide a security solution" is meaningless marketing drivel). Then you look for ways to satisfy those specific requirements; croptography will satisfy some of them.
Example of requirements that cryptography can satisfy:
Protect data sent over publich channels from spying
Protect data against tampering (or rather, detect manipulated data)
Allow servers and clients as well as users to prove their identity to each other
You need to go through the same process as for any other requirement. What is the problem being solved, what is the outcome the users are looking for, how is the solution proposed going to be supported going forward, what are the timescales involved. Sometimes there is an off the shelf solution that does the job, sometimes what you want needs to be developed as a custom solution, and sometimes you'll choose a custom solution as it will work out more cost effective than an off the shelf one.
The same is true with security requirements, but the added complexity is that to do any sort of custom solution requires additional expertise in the technical teams (development, support etc). There is also the issue that the solution may need to be not only secure but recognised as secure. This may be far easier to achieve with an off the shelf solution.
And RickNZ is absolutely right - don't forget key management. Consider this right at the outset as part of the decision making process.
The question I would start by asking, is what are you trying to achieve.
If you are trying to just secure the transmission of the data from server a to server b, then there are a number of mechanisms you could use, which would require little work, such as SSL.
However if you are trying to secure all of the data stored in the application that is a far more difficult, although if it is a requirement, then I would suggest that any cryptography, regardless of how easy to break, is better than none.
As someone who has been asked to do similar things, you face a daunting number of questions in implementing your system. There are major difference between securing a system and implementing cryptography systems.
Implementing a cryptography system is very difficult and experts routinely get it wrong, both in theory and practice. A famous theoretical failure was the knapsack cryptosystem which has been largely abandoned due to the Lenstra–Lenstra–Lovász lattice basis reduction algorithm. On the other side, we saw in the last year how an incorrect seed in Debian's random number generator opened up any key generated by the OS. You want to use a prepackaged cryptosystem, not because its an "experts-only" field, but because you want a community tested and supported system. Almost every cryptographic algorithm I know of has bounds that assume certain tasks to be hard, and if those tasks turn out to be computable (as in the LLL algorithm) the whole system becomes useless over night.
But, I believe, the real heart of the question is how to use things in order to make a secure system. While there are many libraries out there to generate keys, cipher the text, and so on, there are very few systems that implement the entire package. But as always security boils down to two concepts: worth of protection and circle of trust.
If you are guarding the Hope diamond, you spend a lot of money designing a system to protect it, employ a constant force to watch it, and hire crackers to continually try to break in. If you are just discouraging bored teenagers from reading your email, you hack something up in an hour and you don't use that address for secret company documents.
Additionally managing the circle of trust is just as difficult of a task. If your circle includes tech savvy, like-minded friends, you make a system and give them a large amount of trust with the system. If it includes many levels of trust, such as users, admins, and so on, you have a tiered system. Since you have to manage more and more interactions with a larger circle, the bugs in the larger system become more weaknesses to hack and thus you must be extremely careful in designing this system.
Now to answer your question. You hire a security expert the moment the item you're protecting is valuable enough and your circle of trust includes those you cannot trust. You don't design cryptography systems unless you do it for a living and have a community to break them, it is a full time academic discipline. If you want to hack for fun, remember that it is only for fun and don't let the value of what you are protecting get too high.
Pay for security (of which cryptography is a part but only a part) what it is worth but no more. So your first task is to decide what your security is worth, or or how much various states of security are worth. Then invite whoever holds the budget to select which state to aim for and therefore how much to spend.
No absolutes here, it's all relative.
Why buy cryptography? It's one of the most developed area in open source software of great quality :) See for example TrueCrypt or OpenSSL
There is a good chance that whatever you need cryptography for there is already a good quality, reputable open source project for it! (And if you can see the source you can see what they did; I once saw an article about a commercial software supposed to "encrypt" a file that simply xorred every byte with a fixed value!)
And, also, why would you want to re-invent the wheel? It's unlikely that with no cryptography background you will do better or even come close to the current algorithms such as AES.
I think it totally depends on what you are trying to achieve.
Does the data need to be stored encrypted at either end or does it just need to be encrypted whilst in transit?
How are you transferring the data? FTP, HTTP etc?
Probably not a good idea to have security as a second phase as by that point presumably you've been moving data around insecurely for a period of time?
I'm modifying existing security code. The specifications are pretty clear, there is example code, but I'm no cryptographic expert. In fact, the example code has a disclaimer saying, in effect, "Don't use this code verbatim."
While auditing the code I'm to modify (which is supposedly feature complete) I ran across this little gem which is used in generating the challenge:
static uint16 randomSeed;
...
uint16 GetRandomValue(void)
{
return randomSeed++;/* This is not a good example of very random generation :o) */
}
Of course, the first thing I immediately did was pass it around the office so we could all get a laugh.
The programmer who produced this code knew it wasn't a good algorithm (as indicated by the comment), but I don't think they understood the security implications. They didn't even bother to call it in the main loop so it would at least turn into a free running counter - still not ideal, but worlds beyond this.
However, I know that the code I produce is going to similarly cause a real security guru to chuckle or quake.
What are the most common security problems, specific to cryptography, that I need to understand?
What are some good resources that will give me suitable knowledge about what I should know beyond common mistakes?
-Adam
Don't try to roll your own - use a standard library if at all possible. Subtle changes to security code can have a huge impact that aren't easy to spot, but can open security holes. For example, two modified lines to one library opened a hole that wasn't readily apparent for quite some time.
Applied Cryptography is an excellent book to help you understand crypto and code. It goes over a lot of fundamentals, like how block ciphers work, and why choosing a poor cipher mode will make your code useless even if you're using a perfectly implemented version of AES.
Some things to watch out for:
Poor Sources of Randomness
Trying to design your own algorithm or protocol - don't do it, ever.
Not getting it code reviewed. Preferably by publishing it online.
Not using a well established library and trying to write it yourself.
Crypto as a panacea - encrypting data does not magically make it safe
Key Management. These days it's often easier to steal the key with a side-channel attack than to attack the crypto.
Your question shows one of the more common ones: poor sources of randomness. It doesn't matter if you use a 256 bit key if they bits aren't random enough.
Number 2 is probably assuming that you can design a system better than the experts. This is an area where a quality implementation of a standard is almost certainly going to be better than innovation. Remember, it took 3 major versions before SSL was really secure. We think.
IMHO, there are four levels of attacks you should be aware of:
social engineering attacks. You should train your users not to do stupid things and write your software such that it is difficult for users to do stupid things. I don't know of any good reference about this stuff.
don't execute arbitrary code (buffer overflows, xss exploits, sql injection are all grouped here). The minimal thing to do in order to learn about this is to read Writing Secure Code from someone at MS and watching the How to Break Web Software google tech talk. This should also teach you a bit about defense in depth.
logical attacks. If your code is manipulating plain-text, certificates, signatures, cipher-texts, public keys or any other cryptographic objects, you should be aware that handling them in bad ways can lead to bad things. Minimal things you should be aware about include offline&online dictionary attacks, replay attacks, man-in-the-middle attacks. The starting point to learning about this and generally a very good reference for you is http://www.soe.ucsc.edu/~abadi/Papers/gep-ieee.ps
cryptographic attacks. Cryptographic vulnerabilities include:
stuff you can avoid: bad random number generation, usage of a broken hash function, broken implementation of security primitive (e.g. engineer forgets a -1 somewhere in the code, which renders the encryption function reversible)
stuff you cannot avoid except by being as up-to-date as possible: new attack against a hash function or an encryption function (see e.g. recent MD5 talk), new attack technique (see e.g. recent attacks against protocols that send encrypted voice over the network)
A good reference in general should be Applied Cryptography.
Also, it is very worrying to me that stuff that goes on a mobile device which is probably locked and difficult to update is written by someone who is asking about security on stackoverflow. I believe your case would one of the few cases where you need an external (good) consultant that helps you get the details right. Even if you hire a security consultant, which I recommend you to do, please also read the above (minimalistic) references.
What are the most common security problems, specific to cryptography, that I need to understand?
Easy - you(1) are not smart enough to come up with your own algorithm.
(1) And by you, I mean you, me and everyone else reading this site...except for possibly Alan Kay and Jon Skeet.
I'm not a crypto guy either, but S-boxes can be troublesome when messed with (and they do make a difference). You also need a real source of entropy, not just a PRNG (no matter how random it looks). PRNGs are useless. Next, you should ensure the entropy source isn't deterministic and that it can't be tampered with.
My humble advice is: stick with known crypto algorithms, unless you're an expert and understand the risks. You could be better off using some tested, publicly-available open source / public domain code.