int.TryParse
is probably a tad easier:
public static int? ToNullableInt(this string s)
{
int i;
if (int.TryParse(s, out i)) return i;
return null;
}
Edit @Glenn int.TryParse
is "built into the framework". It and int.Parse
are the way to parse strings to ints.
How about taking another approach or angle at this problem? Ask why the password is required to be in plaintext: if it's so that the user can retrieve the password, then strictly speaking you don't really need to retrieve the password they set (they don't remember what it is anyway), you need to be able to give them a password they can use.
Think about it: if the user needs to retrieve the password, it's because they've forgotten it. In which case a new password is just as good as the old one. But, one of the drawbacks of common password reset mechanisms used today is that the generated passwords produced in a reset operation are generally a bunch of random characters, so they're difficult for the user to simply type in correctly unless they copy-n-paste. That can be a problem for less savvy computer users.
One way around that problem is to provide auto-generated passwords that are more or less natural language text. While natural language strings might not have the entropy that a string of random characters of the same length has, there's nothing that says your auto-generated password needs to have only 8 (or 10 or 12) characters. Get a high-entropy auto-generated passphrase by stringing together several random words (leave a space between them, so they're still recognizable and typeable by anyone who can read). Six random words of varying length are probably easier to type correctly and with confidence than 10 random characters, and they can have a higher entropy as well. For example, the entropy of a 10 character password drawn randomly from uppercase, lowercase, digits and 10 punctuation symbols (for a total of 72 valid symbols) would have an entropy of 61.7 bits. Using a dictionary of 7776 words (as Diceware uses) which could be randomly selected for a six word passphrase, the passphrase would have an entropy of 77.4 bits. See the Diceware FAQ for more info.
I know I'd prefer typing the phrase, and with copy-n-paste, the phrase is no less easy to use that the password either, so no loss there. Of course if your website (or whatever the protected asset is) doesn't need 77 bits of entropy for an auto-generated passphrase, generate fewer words (which I'm sure your users would appreciate).
I understand the arguments that there are password protected assets that really don't have a high level of value, so the breach of a password might not be the end of the world. For example, I probably wouldn't care if 80% of the passwords I use on various websites was breached: all that could happen is a someone spamming or posting under my name for a while. That wouldn't be great, but it's not like they'd be breaking into my bank account. However, given the fact that many people use the same password for their web forum sites as they do for their bank accounts (and probably national security databases), I think it would be best to handle even those 'low-value' passwords as non-recoverable.
Best Answer
Hash the password. Don't encrypt - it's complex and/or unsafe. There's no conceivable circumstance in which it wouldn't be OK to reset the password based on some other verifiable criterion in an ordinary line-of-business app or Web site. I'm not sure from the question whether or not you're familiar with the principle of hashing a password, so I'll explain from the basics...
When the user selects their password initially, you run a one-way hash algorithm on the text. This produces a signature - an output that will always be produced if you input the same string into the hash algorithm. The key is that you can't get back to the password from the hash (hence one-way). You then store the hash, not the password. When the user comes back they have to type in their password again, you hash this using the same algorithm and compare the resulting value to what's in the DB - if they match, you know the user enterered the same string again, but you still don't know, or need to know, what it is. This is much more secure than solutions based on encyrption where you can always recover the plaintext if you know the key, which by definition has to be known to the server in order to validate the password input.
A simple way of hashing a string in .NET is to use
System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile()
, which despite its lengthy name is a simple function provided for those using ASP.NET Forms Authentication, but just as useful elsewhere. You can specify MD5 or SHA1 as your hash algorithm (or indeed other hash algorithms if supported by future framework versions). I recommend SHA1 because MD5 is known to have weaknesses, but then SHA1 probably does too.However - there's a flaw in this scheme. If multiple users choose the same password, they will have the same hash. If a hacker gets access to your data, they can run a brute-force attack hashing common strings and comparing these against your stored data. If they get a hit, they've cracked all the accounts using that password. Since users tend to pick crappy passwords and hate being made to pick secure ones they can't remember, this makes a system based on simple password hashes a little brittle.
What you should do is salt the hash. This just means prepending or suffixing the original data - the password - with a random string of characters. This salt needs to be as random as it can be and at least a few chars in length (I recommend 5 as a minimum) and preferably of random length. You store the salt (unobfuscated) in a column in the DB alongside the hashed salt + password combination. When the user returns you prepend or suffix the salt to their input in the same way, and then do the hash comparison as before.
This reduces the effectiveness of a brute force attack because every user should have a different hash even if they have the same password. You can safely store the salt in the DB because working out a string from its hash is just as hard when you know some of the string as it is when you know none of it, provided the password itself is longer than the salt and long enough and strong enough to take a long time to crack by brute force (at least 6 chars with at least one case change and a number or non-alphanumeric, I'd say).
If someone has unlimited access to your data for unlimited time, they'll eventually crack the hashed passwords. But eventually could be months or years. And provided you know you've been compromised, you can get everyone's password changed well before it becomes a problem.