Best way to authenticate users? - asp.net

I realize this question maybe subjective, but I'm fairly new at this and while there is A LOT on this subject. I’ve yet to be able to form a good opinion on this and I'm thinking that maybe due in part that because I'm new I can only think in terms of my project, which isn’t anything out of the ordinary.
So I’m asking in my environment what is the best option for authentication? What method is best sessions? cookies? Something else? Also how do you save passwords in a table safely? I researched data types, but that seem to yield any help. Is there something special that you have to do the table and/or column? Eventually I would love to add other authentication methods to my site {ie Facebook, Google, OpenID}, but I think I need to understand this first.
My environment is ASP.NET with the code behind in VB. I am using MSSQL 2005 (But have access to 2008 if need be).
Thanks
Josh

I'm not familiar with ASP, so I can't answer you on how best to communicate and keep the credentials throughout the session. It sounds like using the built-in membership system, as others have suggested, is the safest approach. I totally sympathize, however, with your desire to do things yourself and understand how they are working under-the-hood. If you do want to tackle doing this yourself, I can speak to the database side of things.
If at all possible, don't ever store the actual password anywhere. You should only be storing an irreversibly-encrypted value generated from the password (using a hash-encryption algorithm such as SHA512Managed). To authenticate the user, rather than decrypting the stored password and comparing the two plain-text passwords, you want to encrypt the entered password and then compare the two encrypted values. If you store the actual password, even if it's encrypted with a reversible-encryption algorithm, it is a big security risk.
Also, if you are using an encryption algorithm that allows you to specify a seed value, you should use an algorithm to generate the seed value based on the original password. You don't want to use the same encryption-seed value for every password.
Also, most encryption methods are designed to be fast so that they can be used for communication streams. However, if they are fast, that means someone can brute-force crack them more quickly. Therefore, the best method for making your encryption safer is to make them as slow as is reasonably possible. Often this is accomplished by re-encrypting the encrypted value over and over again in a loop for a fixed number of times.

Related

encrypt on server decrypt on client

I'm building a simple trivia game that has "hangman" style clues (where letters are revealed as the player asks for hints). I don't want to flat out send the answer with the question any user with sufficient smarts could figure it out) - rather I'd like to encrypt answers on the server and decrypt them on the client. Security isn't of huge importance I just want to make the process harder then it's worth for players. I was wondering if anyone could recommend a strategy for doing this?
A simple approach, which might be sufficiently difficult for most users, would be to send the answer and encryption key to the web client (as hidden form fields), and use Javascript to decrypt it on the fly (inside the browser). A simple exclusive-or'ing of the answer string characters with the key string should be sufficient to "shroud" the answer without requiring large amounts of crypto processing on the client side. Using more than one key string might increase the difficulty of cracking it, too.
I'm assuming that you don't want to implement full commercial-grade crypto on the client side, and also assuming that you only want to hide the answers for a few minutes at most.

Using AES256 as "decryption" in MachineKey for SqlMembershipProvider

I'm creating custom registration forms for Forms Based Authentication for a SharePoint 2010 site, and storing passwords as 'Encrypted' in the aspnet_Membership database table.
My setting in web.config shows that the 'decryption' parameter is "AES". My boss is asking that I look to use AES256, as it's more secure, but I'm having trouble working out how to do this. I've been Googling and "stackoverflow-ing", but so far I've not been able to find that one post that either explains what I need to do, or where to look for good information.
My questions, I think, are:
is "AES256" a valid value for the "decryption" parameter of ?
if not, is simply generating a longer "decryptionkey" all that's required to make AES stonger? i.e. if I make my decryption key 64 characters long, would that constitute AES256?
if I'm totally off base with my current thinking, can anyone put me on track, or explain (or link to an explanation of) how to update my web.config to use AES256 rather than the default AES?
Just in case anyone wants to say "You should use Hashed".. been there, discussed that, decision made to use Encrypted. Just thought I'd get that out of the way :)
No, you can only use "AES" as the decryption parameter for the AES algorithm.
Yes, if you generate one that is 256 bits (64 bytes) long, you effectively have AES256. In reality, you could generate one that is 512 bits long, too. The longer this value is, the stronger the encryption.
No need. You seem to be understanding it.
Now, in .NET 4.0, they've enhanced this a bit, allowing SHA256 to be used for validation as well. See MSDN's documentation (archive.org snapshot) for details.

Instead of using common ciphers such as AES or blowfish twofish, how creating my own cipher?

I don't know much about the heavy math behind cryptosystems, I get stuck when it gets bad with the Z/nZ algebra, and sometimes with all these exponent of exponents. It's not I don't like it, it's just that the information you find on the web are not easy to follow blindly.
I was wondering: how reliable can a algorithm be when it encodes a message into plain binary. If my algorithm is arbitrary and known only to me, how can a cryptanalist study an encrypted file and decrypt it, with or without having the decoded file ?
I'm thinking about not using ASCII text to code my message, and I have some ideas to make this algorithm/program.
Attacking a AES or blowfish crypted file is more trivial for a cryptanalyst, than if the algorithm the file is encrypted with is unknown to him, but how does he do then ?
I don't know if I understanded well, but a CS teacher once told me that codes are harder to crack that crypted ciphers.
What do you think ?
Attacking a AES or blowfish crypted file is more trivial for a cryptanalyst, than if the algorithm the file is encrypted with is unknown to him...
What about:
Attacking an untested self written algorithm with no real research is more trivial for a cryptanalyst, than if the algorithm the file is encrypted with, is a well known and proofed one, that has been correctly used....
In short, DO NOT roll your own cryptography unless you're an expert, no unless you're part of an expert group in that field.
Nintendo failed when they implemented RSA on their own in the Wii, Sony failed too when using it in the PS3 (they pretty much used XKCD's random number function for M...)
And you really think you can win by using security by obscurity?
PS: That doesn't mean that you should take the Wikipedia entry on RSA and roll you own implementation from that one (that's exactly were Sony and Big-N failed), no use a tested, open source implementation.
You seem to be using two words interchangeably but remember that Encoding is Not Encryption
When the attacker has no idea which algorithm you used and it is safe, cryptoanalyst has a hard job. So it is unimportant if you use AES or your own cipher as long as it is as strong and safe as AES. Here is the but. Cryptography is a bit demanding and therefore you have many ways to shoot yourself in a foot without knowing it. I would suggest using standard algorithms, maybe with some safe variations.
Common wisdom is that you should not build your own algorithms, and especially not rely on these algorithms remaining secret.
The conceptual reason is that good encryption is about quantified confidentiality. We do not want our secrets to get cracked, but in a more precise way we want to be able to tell how much it would cost to crack our secrets (and hopefully show that the cost is way too high to be envisioned by any entity on Earth). This is the real advance which occurred a few years after World War II: to understand the distinction between key and algorithm. The key concentrates the secret. The algorithm becomes the implementation.
Since the implementation is, well, implemented, it exists as some code or a device, which is tangible and stored even when it is not used. Keeping an implementation secret requires keeping track of the hard disk on which the code resides at all times. If the attacker sees the binary code, he may be able to reverse-engineer it, something which depends on his wits and patience. The point here is that it is very difficult to be able to say: "it costs X dollars to recover a description of the algorithm".
On the other hand, the key is short. It can be stored safely much more easily; e.g. you could memorize it, and avoid committing it to any permanent storage device. You then have to worry about your key only at times when you use it (and not when you do not, e.g. in the middle of the night, when you sleep). The number of possible keys is a simple mathematical problem. You can easily and accurately estimate the average cost of enumerating the possible keys until your key is found. The key is a sturdy foundation for quantified security.
So you should not roll your own algorithms because then you do not know how much security you get.
Also, most people who rolled their own algorithms found out, usually the hard way, that they did not get much security at all. Designing a good encryption algorithm is hard, because it cannot be automatically tested. Your code may run, and properly decrypt data that it encrypted, but it tells you nothing about how secure the algorithm is. The design of the AES was the result of a process which took several years and involved hundreds of skilled cryptographers (most of whom had a PhD and years of experience in academic research on symmetric encryption). That a lone developer could do as well, let alone better, in the secrecy of his own workshop, looks kind of... implausible.
The biggest part of your strategy is called "security through obscurity." You're making the gamble that, since nobody knows the precise details of your little variation on an idea, they won't be able to figure it out.
I'm not a security expert, but I can tell you that you probably won't come up with something incredibly new. Cryptography has been studied by people for millenia and your idea is highly unlikely to be original. Even if you're a relatively good programmer and code something really tricky, the question will come down to who you're up against. If you're just trying to protect your data from your kid sister, then it will probably be fine. On the other hand, if you're using it to send credit card numbers across the internet, then you're doomed to fail. It will be analysed in ways you didn't think of or don't know, and ultimately cracked.
Another way to think of it: algorithms like AES have been extensively studied by professionals in the field and its level of security is pretty well understood. Anything you come up with by yourself will not have the benefit of having been attacked by the best and brightest minds out there. You will have almost no idea of how good it actually is until people start reporting identity theft.

Extending ASP.NET role providers

Because the RoleProvider interface seems to treat roles as nothing more than simple strings, I'm wondering if there is any non-hacky way to apply an optional value for a role on a per-user basis.
Our current login management system implements roles as key-value pairs, where the value part is optional and usually used to clarify or limit the permissions granted by a role.
For example, a role 'editor' might contain a user 'barry', but for 'barry' it will have an optional value 'raptors', which the system would interpret to mean that Barry can only edit articles filed under the 'raptors' category.
I have seen elsewhere a suggestion to simply create additional delimited roles, such as 'editor.raptors' or somesuch. That's not really going to be ideal because it would bloat the number of roles greatly, and I can tell it's going to be a very hard sell to replace our current implementation (which is also very less than ideal, but has the advantage of being custom made to work with our user database).
I can tell already that the concatenation method mentioned above is going to involve a lot of tedious string-splitting and partial matching.
Is there a better way?
EDIT: My initial goal was to use more built-in ASP.NET functionality. For instance, control access via <authorization/> elements in the Web.config. Doing this, as far as I can see, requires implementing roles themselves. Our current system's concept of auths seemed to fit very well apart from that one limitation.
Answering mnemosyn's questions
Yes. We have a central database for users, applications and their authorisations. It's a core system and there's no going around it.
Currently our system is not hierarchical, and it actually takes quite a lot of effort to maintain. When an application is created, a set of authorisations are defined (e.g., 'admin', 'user', 'poweruser', 'gatekeeper', 'keymaster', etc.). Users are then associated with those authorisations with the optional value for a unique combination of user and (app-specific) authorisation.
Can you elaborate on these 'categories' of which you speak?
This really sounds like an architectural issue to me.
First, you need to determine what you need, exactly. In a second step, map this to a concrete implementation. To jump ahead on that one: I wouldn't use the built-in providers for anything but the most simplistic cases. Also, this problem quickly gets very complicated, so I'd try to keep it as simple as possible.
To elaborate your needs, try to determine:
Do you really need to map the role concept to the database, as you would in a CMS? Or do changes to your role system imply a modification to the system. In that case, you could go for a much simpler solution and put an enum into the user. This will save a lot of database accesses, makes joins simple selects, etc.
What are you trying to achieve through the multi-role concept you explained? Is it really roles that you need? How about individual permissions? Do you, for instance, have a hierarchical structure so that every node can have a certain set of permissions associated with it, much like windows' file security concept?
If it's only categories, why not map categories to users, i.e. give each user a certain role in each category. This will require some tweaks for default category, etc.
A few tips there: Don't go for whitelists, always use blacklists. Controlling whitelists is a pain, esp. when a lot of rules come together. In drupal, for example, I think this is one of the major flaws (which is why they're rebuilding it to use blacklists in version 7). Allowing a user to do something they shouldn't is usually a much bigger issue than the other way around.
The windows file access concept is very complicated, because it has both black- and whitelisting, which additionally can be inherited - so try to keep your solution much simpler than that.
The string concatenation thingie sounds rather dangerous to me, I'd go for a cleaner solution in any case. This type of meta-logic gives headache.

How to prevent user from decrypting data file while the program is capable to read the data file freely?

I want to ask for a mature model to do this.
Suppose I want to deliver a program and a sensitive data file to user. The program is able to read any data stored in the data file, but user is not allowd to easly break the data file. The data file will be encrypted by standard algorithm such as AES. Now, the problem turns to how to manage the key. Putting the key in the program seems to be a bad idea, but what else I can do? Apparently I can't give the key to user directly.
There is no way to do this securely, ie. to really prevent the user from reading the data. As long as they have the data and they have the program that can read it a competent disassembler will be able to figure out how the program reads it and do the same thing. Or, even easier, they could let the program do it and then get the decrypted version out of its memory.
Having said that, if you just want to prevent the average user from doing it, hardcoding the key in your source code should be fine. :) Just be realistic about the level of protection this provides.
Does it have to be pure software? If not, you could look at a solution which does decryption and storage of the key on a hardware device, e.g. a USB dongle.
You can also potentially prevent the whole problem by having your software retireve the data from a web-service instead of a data file. In this case you can control access to the data much more tightly (i.e. who gets how much of what and when). This might or might not work for your application.
Otherwise as others pointed out, there is no known good pure software solution.
There is no 100% safe solution to this because at some point you have to have the key loaded into memory so that de/encryption can take place and a savvy-enough hacker will be able to capture it. The best you can do is to make it very difficult to capture and to mitigate exposure to data (by limiting access as much as possible) if the key is compromised.
As far as how to make it safer... you could have a combined key that is made up of something stored in the program and something derived from the user's passcode?
Is your perceived user determined? are they skilled enough to do reverse the application or the key? If the user is considered to just be a generic desktop user you probably could implement a partial key using some general encryption just to make the key non obvious, beyond that a determined individual will be able to reverse must simple means of encrypting keys and data.
A DVD John conundrum, eh? Why is having a key in the program bad? You could have a super-obscured function which computes it reliably once. Someone with disassembler and debugger can break your key given enough time, IMO.

Resources