Authenticating by using some letters from the password - authentication

How do banks authenticate users just by asking some letters of the password. Does is mean that hashes of those individual words are stored in the database, and if yes then would not it make it very vulnerable to break those passwords. Can you please give me some insight in how they do it.
Thanks

It does not matter if they hash this information or not. This way of proceeding is totally unsafe and makes the system very weak. So, the way they do it is really the 'wrong' way.

Related

Now that I know how to salt & hash passwords, a few more questions

So, let's assume I have read every article/post about appropriately salting and hashing passwords in order to secure user credentials.
This means I am not wondering what hashing algorithm to use (SHA1 vs. SHA2 vs. PDKBF2), how to generate the salt, how to store the salt, how to append the salt, or whether I should be writing the code myself vs. leveraging well-established libraries like bcrypt. Please, avoid rambling about these issues here as I have read 50+ other pages of that already.
Just assume the following is my approach (also note I understand this is not flawless or likely sufficient for applications like financial service, I am really just wondering if this is an acceptable min bar to claim that I "do the right thing").
User comes to my amazing website (www.myamazingwebsite.com) and logs in with email and pass.
I pull her salt and hash from my database. Assume the salt is lengthy enough, unique per-user, and created using a CSPRNG upon user registration.
I prepend the salt to her input password, hash it using SHA-512, run 1,000 iterations, then compare it to the hashed value pulled from the db:
var hash = sha512(salt + password);
for (i = 0; i < 1000; i++) {
hash = sha512(salt + password + hash);
}
If they match, the user is authenticated. Otherwise, they are not.
Now, my question is how secure is my above approach. The questions I would like help answering:
Do I need to change the salt periodically? For example, perhaps I could re-compute and store a new hash using a newly created random salt after every successful login. This seems like it would be more secure but I am not sure what standard practice is here.
The request to the server will be done via https. Does that mean I can assume that I can process all of the hashing and validation logic server side? Would most folks consider this sufficient, or do I need to consider some hybrid both on client and server side?
Anything else I am overlooking or need to consider?
Thanks in advance, I appreciate the help.
1) Assuming you've done the right thing and do not store their password, you can't change the salt unless they are logging in. I suppose you could change their salt every time they do log in, but it doesn't really help (and might hurt).
Here's why: Having a unique salt on everyone simply makes it harder for an attacker that has access to your database from attempting to guess the passwords. If you've done things correctly, he would have to use a different salt for each person. He can't just start guessing passwords using a site-wide salt and see if it matches anyone. As long as you have a unique salt for each user, you are doing the best you can.
In fact, changing the salt does nothing but give an attacker with access to your database over time MORE information. Now he knows what their password looks like salted two different ways. That could (theoretically) help crack it. For this reason, it would actually be ill advised to change the salt.
2) Https is sufficient. If someone can compromise https, then any additional client side hashing or such will not help. The clients computer is compromised.
3) I think you have a fair understanding of best password practices. Don't overlook other security issues like sql-injection and cross-site scripting.
Do I need to change the salt periodically?
No. The salt is a per-user public parameter that servers two purposes. First, it ensures that an attacker cannot build an offline dictionary of passwords to hashes. Second, it ensures two users with the same password have different hashed password entries in the database.
See the Secure Password Storage Cheat Sheet and Secure Password Storage paper by John Steven of OWASP. It takes you through the entire threat model, and explains why things are done in particular ways.
The request to the server will be done via https. Does that mean I can assume that I can process all of the hashing and validation logic server side?
This is standard practice, but its a bad idea. Its a bad idea because of all the problems with SSL/TLS and PKI in practice. Though this is common, here's how it fails: the SSL/TLS channel is setup with any server that presents a certificate. The web application then puts the {username, password} on the wire in the plain text using a basic_auth scheme. Now the bad guy has the username and password.
There's lots of other problems with doing things this way. Peter Gutmann talks about this problem (and more) in his Engineering Security book. He's got a witty sense of humor, so the book is cleverly funny at times, too even though its a technical book.
Would most folks consider this sufficient, or do I need to consider some hybrid both on client and server side?
If possible, use TLS-PSK (Preshared Key) or TLS-SRP (Secure Remote Password). Both overcome the problems of basic_auth schemes, both properly bind the channel, and both provide mutual authentication. There are 80 cipher suites available for TLS-PSK and TLS-SRP, so there's no shortage of algorithms.
Anything else I am overlooking or need to consider?
Cracking is not the only threat here. More than likely, the guy trying to break into your organization is going to be using one of the top passwords from the millions of passwords gathered from the Adobe breach, the LinkedIn breach, the Last.fm breach, the <favorite here> breach.... For example:
25 most-used passwords revealed: Is yours one of them?
The 30 Most Popular Passwords Stolen From LinkedIn
Top 100 Adobe Passwords with Count
Why bother brute forcing when you have a list of thousands of top rated passwords to use?
So your FIRST best defense is to use a word list that filters a user's bad password choices. That is, don't allow user's to pick weak or known passwords in the first place.
If someone gets away with your password database, then he or she is going to use those same password lists to try and guess your user's passwords. He or she is probably not even going to bother brute forcing because he or she will have recovered so many passwords using a password list.
As I understand it, these word lists are quite small when implemented as a Bloom Filter. They are only KB in size even though there are millions of passwords. See Peter Gutmann's Engineering Security for an in depth discussion.

Salting the Password with the Password

I am developing my first web app that requires a login, and it has come to the point when i must decide how to store the passwords. I have been doing a lot of reading on the proper way to hash the password and adding a salt. It occurred to me that most of the ways that are recommended would rely on some variation of information that is stored in the database with the password hash, be it some variation of using all or part of the username as a salt or some other random value.
Instead I was thinking of using the user own password as a salt on the password. Using an algorithm to jumble the password and adding it to itself in some way as the salt. Of course this to would be compromised if an attacker got access to both the stored hashes and the source code of the algorithm, but any salt would be compromised in such a situation. My application really probably does not need this level of security, but it was just something that i started to think about when reading.
I just wanted to get some feedback from some more experienced developers. Any feedback is appreciated.
If you derrive the salt from the password itself, you will loose the whole benefit of salting. You can then build a single rainbow-table to get all passwords, and equal passwords will result in equal hash-values.
The main reason to use a salt is, that an attacker cannot build one single rainbow-table, and get all the passwords stored in your database. That's why you should add a random unique salt for each password, then an attacker would have to build a rainbow table for each password separately. Building a rainbow-table for a single password makes no sense, because brute forcing is faster (why not just stop when the password was found).
Don't be afraid to do it right, often the programing environments have support to create safe hashes and will handle salting for your (e.g. password_hash() for PHP). The salt is often combined with the hash for storing, that makes it easy to store it in a single database field.
I wrote a small tutorial about securely storing passwords, maybe you want to have a look at it.
Simply duplicating the password may still be vulnerable to dictionary attacks, e.g. the password "hello" becomes "hellohello", and thus might be part of a dictionary.
Using a scrambled password as the salt enables the attacker to use a dictionary and then generate a rainbow table for all entries by adding the scambled password on every entry.
Why change a proven algorithm which can be understood by any developer? Just do it the default way and your code will be maintainable by anyone else.
"My application really probably does not need this level of security" - until that point in time it was hacked. Use a salt, it takes almost no additional effort. Do it now.
"eliminate the need of storing the password salt at all": the salt can be very small (6 bytes). It will hardly affect performance.
I just wanted to get some feedback from some more experienced developers. Any feedback is appreciated.
John Steven of OWASP performed an analysis, including threat modes, for password storage system. It explains the components and their purpose, like the hash, the iteration count, the salt, the HMACs, the HSMs, etc. See the Secure Password Storage Cheat Sheet and Secure Password Storage paper.
Cracking is not the only threat here. More than likely, the guy trying to break into your organization is going to be using one of the top passwords from the millions of passwords gathered from the Adobe breach, the LinkedIn breach, the Last.fm breach, the eHarmony breach, the <favorite here> breach.... For example:
25 most-used passwords revealed: Is yours one of them?
The 30 Most Popular Passwords Stolen From LinkedIn
Top 100 Adobe Passwords with Count
Why bother brute forcing when you have a list of thousands of top rated passwords to use?
So your FIRST best defense is to use a word list that filters a user's bad password choices. That is, don't allow user's to pick weak or known passwords in the first place.
If someone gets away with your password database, then he or she is going to use those same password lists to try and guess your user's passwords. He or she is probably not even going to bother brute forcing because he or she will have recovered so many passwords using a password list.
As I understand it, these word lists are quite small when implemented as a Bloom Filter. They are only KB in size even though there are millions of passwords. See Peter Gutmann's Engineering Security for an in depth discussion.

What algorithm should I use for encrypting and embedding a password for an application?

What algorithm should I use for encrypting and embedding a password for an application?
It obviously is not bullet proof, but it should be good enough to thwart someone scanning the database with a hex editor, or make it hard for someone who has the skills to use a debugger to trace the code to work out, either by scanning for the encrypted password, or using a debugger to run through the decryption code.
Object Pascal would be nice.
Major Edit
I think I did not explain myself well enough. The password needs to be decrypted back into its original form and applied. The application itself uses a local SQL database and a local webserver, and the password is fixed and can't be changed by the end users. It is to ensure that changes to be made only from within the app itself. The user passwords are only to allow access to the app itself, rather than the database
/vfclists
If you want an easy solution just stick with a good hashing algorithm like MD5 and store just the hash inside your application. Then whenever the user inserts the password you will calculate the hash of the password and check if it's equal to the one stored.
Of course this approach is a simple solution that doesn't allow you to retrieve the password if it's lost but it should work quite fine if you just need some protection..
EDIT: I mentioned MD5 that was fair good but not anymore, of course you can choose any other stronger function like SHA-2 (512/384) that is more robust. I just wanted to explain an approach more than using a specific hashing algorithm.
SHA should be ok for you, best with salt.
I don't know Object Pascal very well, but probably this will help you:
http://sourceforge.net/projects/op-crypt/
When an application has to do password checking only, it is best to save a hash. An hash can not be decrypted, but it can be checked whether the password the user enters has the same hash.
If you want to save the password so that it can be recovered, it is best to encrypt it first, using some crypto library.
I would suggest SHA1, its one way encryption, i've used it before and by far no one has decrypted it!
If you need more information on sha1 visit http://en.wikipedia.org/wiki/Secure_Hash_Algorithm and http://www.openssl.org/docs/crypto/sha.html.
PS: If you're using php you can simply encrypt with SHA1 using the sha1(); function!
I suspect that what you're aiming for is not storing passwords in the application, but trying to prevent the application itself from being run without the password, as a form of DRM. If that's the case, and you're looking to stymie people with debuggers, I think you're well into the realm of needing either a hardware dongle, or a network-based lock. Off the top of my head, I know SafeNet carry products that do this (and I've had some exposure to them in the past, they seem decent), but I don't know how well they compare to the rest of the market.
If you want as much real security as is possible in the scenario you're describing, you should require that when the system is installed an "administrator" enters the database password and his own administrator password; the application should then store a salted hash of the administrator's password, and it should store the database password encrypted with a differently-salted hash of the administrator's password. The database password (or information sufficient to reconstruct it) will be kept in memory while the program is running, but absent the administrator password there would be no way to retrieve when the program isn't running, even with full knowledge of the system.
If it's necessary to allow multiple users to access the database, an "add user" button could allow the addition of a user account. When the user types his password, use it to store hashed/encrypted data as with the administrator.
Any user with a debugger would be able to leverage his knowledge of a valid user account and password into knowledge of the database password, but someone who didn't have knowledge of a valid account password wouldn't be able to do anything.
If I am interpreting your question right, then you want to basically distribute your application to users, allow them to run it, and have the application update your database. At the same time, you want to prevent that person from being able to log in to the database and use it themselves directly.
If your program can be decompiled (like java, but I don't know about other languages like C, C++), then the person who has your application will be able to see the source code. Once they have that, there will most certainly be some way they can discover the user name and password. Even if your source code has stored the password using a reversible encryption algorithm, the person who holds your source code will be able to write similar code as yours to reverse the encryption and discover the password.
Even if your application cannot be decompiled, the user may be able to capture the network packets it sends to the database and determine the password from that. I don't know if you can communicate with the database over SSL.
Instead, I believe you need to split your application into client and server applications. You can write a restful web application, or use a messaging service (like JMS for example), and write a client application that uses it.
In that case, you may or may not want to have user accounts that are managed by your server side application. Let me be clear here, I am not talking about database accounts, but accounts that your application manages, and whose details happen to be stored in the database. If you do create user accounts, you can follow the pattern in my original answer shown below.
============== Hashing Approach, my original answer ============
As others have already mentioned, it's best to add salt to the password and use a digest algorithm before you store the password in your database. However, I think a little more detail is in order.
Using SHA1 or SHA2 with a salt value may be pretty strong, but there are even stronger methods. I highly recommend that you read this section of the spring security manual. I don't think you are using spring or java, but that section covers the concepts involved very well. Allow me to paraphrase:
Use at least an 8 byte salt value, up to 16 bytes would be great. The salt value should be different for every account, if it is the same then a cracker will only need to produce one rainbow table! It should be randomly generated. The documentation doesn't say this, but I also recommend using a secure random number generator, don't use a random number seed that produces a consistent sequence of numbers.
You should hash the password multiple times because it will cause brute force password hacking attempts to take increasingly more time. Indeed, you may want a slow password encoding algorithm instead of a fast one.
Store the raw salt value in the database along with the password, you can even store it in the same field/column. This is required so passwords can be verified in the future.
The BCryptPasswordEncoder is a good example of this.
===============
One alternative approach that may or may not solve your problem is to create a database account that has limited privileges. For example, you could create a database account that can only select, update, insert, and delete on specific tables in your database. You may not find this acceptable, because you may not want to let people do those operations directly, while you may want to let the application do those operations. It depends on your specific situation.

Is storing the answer to a secret question any more secure than storing a password?

Reading what is currently the top answer to a recent question on how/whether to send users their passwords, I was intrigued that the most popular answer said the following...
storing passwords in such a way that they are retrievable is insecure
using a reset feature with the help of a secret question is a valid alternative
(These two points seem contradictory.)
I use hashed passwords for security, but I've always assumed that the password question and answer scheme are even less secure because they actually give a hint as to what the answer may be. (I often use .NET's default membership provider.)
Is there something I'm missing because I've not bothered to use the question & answer? Are secret question and answers, without incorporating any sort of timed email reset function, any more secure than storing a password in the db?
Follow Up: Microsoft's membership provider uses the same format for storing answers to secret questions as they do for the password. If you specify hashed for the password, then it will store the secret answer the same way.
From the posts below, it appears that, if used, a secret question/answer mechanism should only be used in addition to an email reset scheme, rather than instead of, and should be hashed as well. This, of course, may present problems for people like me who put long random strings in the secret answer section.
Passwords are answers to a 'secret' question. That question is, "what is your password?".
As Scunliffe points out, adding an additional field of user input may or may not increase the security of the password - that depends on the user's practices.
I allow myself to be guided by OWASP here:
They are unacceptable for the
following reasons:
Collection of information about people without their explicit consent
(such as "Mother's maiden name") is
illegal in most privacy regimes. Such
collection is subject to privacy laws,
review and correction by the subject,
and so on.
IT Security Policies and standards such as ISO 27000 prohibit the clear
text storage of passwords, but almost
all Q&A schemes store both the
question and answer in the clear
The information in the answers is public for a goodly portion of the
users of the Internet, and thus is
found using public sources
Edit (2018): OWASP seems to have re-arranged their materials. The wayback machine captured a copy of the original page.
The question and answer idiom has been exploited in many published "email hacks" (example)- I'd certainly avoid using it.
Secret questions and answers are only as secure as the user makes them to be. If someone knows anything about you, they can answer an easy question and reset your password. I'm guessing answers are also hashed, so that the answer is not directly stored. But again, knowing the answer to the question is all it takes.
A hashed password stored is about as secure as most applications get, and that's fine because it's one way, and thus the plain text is never stored nor can it be retrieved.
I would argue that a secret question/ answer combination is just another form of "password". I would then go on to suggest that a secret answer is probably weaker than a regular password, as there is rarely any suggestion that it should be anything other than regular words that are susceptible to dictionary attacks. In most cases, the dictionary space of the answer is significantly shortened by the context of the question (scunliffe's exception noted, however).
i would use a secret question to determine if I should or shouldn't send them a newly generated password via an email. Never to let them set a new one. At the end of the day though, it all comes down to make it as secure as it needs to be. If you're an online bank or a networking site makes a huge difference.
One site I've been on (bank or health insurance) required me to answer six secret questions. For a password reset, they'd choose three of those at random and require me to answer them.
In addition, I presume they'd only store the hashed answers, not the plain text version. As DDaviesBrackett has said, the password is a secret question.
I feel like part of your question is being overlooked. Cause like you I see how we are somehow overlooking the common sense that if you should not store their password in plain text yet you are willing to store their answer to their 'secret question' in plain text and then allow them reset their password via a link sent through email, than why even have a secret question and just email them their the reset link. Of course you could just as easily encrypt the answer to the question.
It seems that many people, myself included, write their question/answer in some encrypted where the question does not provide a hint, but I'm always asking myself when I create these - "if I don't remember the password that I am going to be using every time I come to this site, how will I ever remember my answer that I made up 2 years ago and have never used."
My Opinion: The whole idea of the 'secret question' is just a sense of false security, as if adding the addition of the secret question is going to make the process of hacking into my account so much harder that the one extra step will frustrate the hacker and cause him to give up.
It seems more likely that it will just provide a clue to a friend or family member you wants to screw with me.
It depends also how related the secret question / answer are.
Case in point, when I'm presented with the option to put in a question I put in something like:
Question: Groovy Broccoli?
Answer: International Space Station 431
These are not actual question/answers I use, but I can assure you that the questions I use provide no clue whatsoever as to the answer.
If you can get into the system by using the secret question, then that system is just as secure as the method with which the secret question is stored.
However, if a user uses their same password on other systems, then at least making sure the password is hashed keeps that user's password from being outted on other systems, like their online bank.
The crux of the security of the secret question usually lies in an alternate trusted communication medium. If the user answers the 'secret question' correctly, the server should provide a random password via the trusted channel (e.g. email address).
Then, using that random password (which is as safe as the user's email), he can use it to log in and change the password to something else.
That depends on the security needs you require... And once they have already answer that part.
The only thing i have to add, its that you use MD5 encryption for storing passwords, and other sensitive data. Be aware that on the present time its next to impossible to discover the "phrase" encrypted by MD5. You can find loads of articles talking about it. And isn't difficult to implement in your projects.
Regards.
Fábio Antunes
"Greetings, Professor Falken."
or
why it is not a good idea to base any authentication scheme on non-secret, non-random-"ish" responses.
And, if you try to be a little tricky and choose random-"ish" responses to the notorious maiden-name-questions and are able to remember them AFTER you have forgotten your password (and probably have changed it a few times since setting the "secret question".
Nay, the whole secret-questions scheme is botched from the start. For a start, the question is not secret but revealed to anybody claiming to have mislaid your password.

Replacing plain text password for app

We are currently storing plain text passwords for a web app that we have.
I keep advocating moving to a password hash but another developer said that this would be less secure -- more passwords could match the hash and a dictionary/hash attack would be faster.
Is there any truth to this argument?
Absolutely none. But it doesn't matter. I've posted a similar response before:
It's unfortunate, but people, even programmers, are just too emotional to be easily be swayed by argument. Once he's invested in his position (and, if you're posting here, he is) you're not likely to convince him with facts alone. What you need to do is switch the burden of proof. You need to get him out looking for data that he hopes will convince you, and in so doing learn the truth. Unfortunately, he has the benefit of the status quo, so you've got a tough road there.
From Wikipedia
Some computer systems store user
passwords, against which to compare
user log on attempts, as cleartext. If
an attacker gains access to such an
internal password store, all passwords
and so all user accounts will be
compromised. If some users employ the
same password for accounts on
different systems, those will be
compromised as well.
More secure systems store each
password in a cryptographically
protected form, so access to the
actual password will still be
difficult for a snooper who gains
internal access to the system, while
validation of user access attempts
remains possible.
A common approache stores only a
"hashed" form of the plaintext
password. When a user types in a
password on such a system, the
password handling software runs
through a cryptographic hash
algorithm, and if the hash value
generated from the user's entry
matches the hash stored in the
password database, the user is
permitted access. The hash value is
created by applying a cryptographic
hash function to a string consisting
of the submitted password and,
usually, another value known as a
salt. The salt prevents attackers from
building a list of hash values for
common passwords. MD5 and SHA1 are
frequently used cryptographic hash
functions.
There is much more that you can read on the subject on that page. In my opinion, and in everything I've read and worked with, hashing is a better scenario unless you use a very small (< 256 bit) algorithm.
There is absolutely no excuse to keeping plain text passwords on the web app. Use a standard hashing algorithm (SHA-1, not MD5!) with a salt value, so that rainbow attacks are impossible.
I don't understand how your other developer things 'more passwords could match the hash'.
There is argument to a 'hash attack would be faster', but only if you're not salting the passwords as they're hashed. Normally, hashing functions allow you to provide a salt which makes the use of known hash table a waste of time.
Personally, I'd say 'no'. Based on the above, as well as the fact that if you do somehow get clear-text expose, a salted, hashed value is of little value to someone trying to get in. Hashing also provides the benefit of making all passwords 'look' the same length.
ie, if hashing any string always results in a 20 character hash, then if you have only the hash to look at, you can't tell whether the original password was eight characters or sixteen for example.
I encountered this exact same issue in my workplace. What I did to convince him that hashing was more secure was to write a SQL injection that returned the list of users and passwords from the public section of our site. It was escalated right away as a major security issue :)
To prevent against dictionary/hash attacks be sure to hash against a token that's unique to each user and static (username/join date/userguid works well)
If you do not salt your Password, you're suspect to Rainbow Table attacks (precompiled Dictionaries that have valid inputs for a given hash)
The other developer should stop talking about security if you're storing passwords in plaintext and start reading about security.
Collisions are possible, but not a big problem for password apps usually (they are mainly a problem in areas where hashes are used as a way to verify the integrity of files).
So: Salt your passwords (by adding the Salt to the right side of the password*) and use a good hashing algorhithm like SHA-1 or preferably SHA-256 or SHA-512.
PS: A bit more detail about Hashes here.
*i'm a bit unsure whether or not the Salt should to to the beginning or to the end of the string. The problem is that if you have a collisions (two inputs with the same hash), adding the Salt to the "wrong" side will not change the resulting hash. In any way, you won't have big problems with Rainbow Tables, only with collisions
There is an old saying about programmers pretending to be cryptographers :)
Jeff Atwood has a good post on the subject: You're Probably Storing Passwords Incorrectly
To reply more extensively, I agree with all of the above, the hash makes it easier in theory to get the user's password since multiple passwords match the same hash. However,
this is much less likely to happen than someone getting access to your database.
There is truth in that if you hash something, yes, there will be collisions so it would be possible for two different passwords to unlock the same account.
From a practical standpoint though, that's a poor argument - A good hashing function (md5 or sha1 would be fine) can pretty much guarantee that for all meaningfully strings, especially short ones, there will be no collisions. Even if there were, having two passwords match for one account isn't a huge problem - If someone is in a position to randomly guess passwords fast enough that they are likely to be able to get in, you've got bigger problems.
I would argue that storing the passwords in plain text represents a much greater security risk than hash collisions in the password matching.
I'm not a security expert but I have a feeling that if plain text were more secure, hashing wouldnt exist in the first place.
In theory, yes. Passwords can be longer (more information) than a hash, so there is a possibility of hash collisions. However, most attacks are dictionary-based, and the probability of collisions is infinitely smaller than a successful direct match.
It depends on what you're defending against. If it's an attacker pulling down your database (or tricking your application into displaying the database), then plaintext passwords are useless. There are many attacks that rely on convincing the application to disgorge it's private data- SQL injection, session hijack, etc. It's often better not to keep the data at all, but to keep the hashed version so bad guys can't easily use it.
As your co-worker suggests, this can be trivially defeated by running the same hash algorithm against a dictionary and using rainbow tables to pull the info out. The usual solution is to use a secret salt plus additional user information to make the hashed results unique- something like:
String hashedPass=CryptUtils.MD5("alsdl;ksahglhkjfsdkjhkjhkfsdlsdf" + user.getCreateDate().toString() + user.getPassword);
As long as your salt is secret, or your attacker doesn't know the precise creation date of the user's record, a dictionary attack will fail- even in the event that they are able to pull down the password field.
Nothing is less secure than storing plain-text passwords. If you're using a decent hashing algorithm (at least SHA-256, but even SHA-1 is better than nothing) then yes, collisions are possible, but it doesn't matter because given a hash, it's impossible* to calculate what strings hash to it. If you hash the username WITH the password, then that possibility goes out the window as well.
* - technically not impossible, but "computationally infeasible"
If the username is "graeme" and the password is "stackoverflow", then create a string "graeme-stackoverflow-1234" where 1234 is a random number, then hash it and store "hashoutput1234" in the database. When it comes to validating a password, take the username, the supplied password and the number from the end of the stored value (the hash has a fixed length so you can always do this) and hash them together, and compare it with the hash part of the stored value.
more passwords could match the hash and a dictionary/hash attack would be faster.
Yes and no. Use a modern hashing algorithm, like an SHA variant, and that argument gets very, very week. Do you really need to be worried if that brute force attack is going to take only 352 years instead of 467 years? (Anecdotal joke there.) The value to be gained (not having the password stored in plain text on the system) far outstrips your colleague's concern.
Hope you forgive me for plugging a solution I wrote on this, using client side JavaScript to hash the password before it's transmitted: http://blog.asgeirnilsen.com/2005/11/password-authentication-without.html