I want to clarify that I know this is not something you want to have to do and that in most cases refusal to do so is best. I am, however, not looking for a lecture on the merits of taking this approach I am looking for the best steps to take if you do take this approach.
In a note below I made the point that websites geared largely toward the elderly, mentally challenged, or very young can become confusing for people when they are asked to perform a secure password recovery routine. Though we may find it simple and mundane in those cases some users need the extra assistance of either having a service tech help them into the system or having it emailed/displayed directly to them.
This has been a fun question with lots of debate and I have enjoyed it. In the end I selected an answer that both retains password security (I will not have to keep plain text or recoverable passwords), but also makes it possible for the user base I specified to log into a system without the major drawbacks I have found from normal password recovery.
Also, thanks to everyone in the Stack community who voted for this question and/or marked it as a favorite. I take hitting 100 up votes as a compliment and hope that this discussion has helped someone else with the same concern that I had.
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.
Architect: This building cannot be built without fire exits. You can go to any other licensed professional and he will tell you the same thing. I'm leaving now; call me back when you are ready to cooperate.
Computer programming may not be a licensed profession, but people often seem to wonder why our profession doesn't get the same respect as a civil or mechanical engineer - well, look no further. Those professions, when handed garbage (or outright dangerous) requirements, will simply refuse. They know it is not an excuse to say, "well, I did my best, but he insisted, and I've gotta do what he says." They could lose their license for that excuse.
I don't know whether or not you or your clients are part of any publicly-traded company, but storing passwords in any recoverable form would cause you to to fail several different types of security audits. The issue is not how difficult it would be for some "hacker" who got access to your database to recover the passwords. The vast majority of security threats are internal. What you need to protect against is some disgruntled employee walking off with all the passwords and selling them to the highest bidder. Using asymmetrical encryption and storing the private key in a separate database does absolutely nothing to prevent this scenario; there's always going to be someone with access to the private database, and that's a serious security risk.
You could encrypt the password + a salt with a public key. For logins just check if the stored value equals the value calculated from the user input + salt. If there comes a time, when the password needs to be restored in plaintext, you can decrypt manually or semi-automatically with the private key. The private key may be stored elsewhere and may additionally be encrypted symmetrically (which will need a human interaction to decrypt the password then).
Don't give up. The weapon you can use to convince your clients is non-repudiability. If you can reconstruct user passwords via any mechanism, you have given their clients a legal non-repudiation mechanism and they can repudiate any transaction that depends on that password, because there is no way the supplier can prove that they didn't reconstruct the password and put the transaction through themselves. If passwords are correctly stored as digests rather than ciphertext, this is impossible, ergo either the end-client executed the transaction himself or breached his duty of care w.r.t. the password. In either case that leaves the liability squarely with him. I've worked on cases where that would amount to hundreds of millions of dollars. Not something you want to get wrong.
You can not ethically store passwords for later plaintext retrieval. It's as simple as that. Even Jon Skeet can not ethically store passwords for later plaintext retrieval. If your users can retrieve passwords in plain text somehow or other, then potentially so too can a hacker who finds a security vulnerability in your code. And that's not just one user's password being compromised, but all of them.
If your clients have a problem with that, tell them that storing passwords recoverably is against the law. Here in the UK at any rate, the Data Protection Act 1998 (in particular, Schedule 1, Part II, Paragraph 9) requires data controllers to use the appropriate technical measures to keep personal data secure, taking into account, among other things, the harm that might be caused if the data were compromised -- which might be considerable for users who share passwords among sites. If they still have trouble grokking the fact that it's a problem, point them to some real-world examples, such as this one.
The simplest way to allow users to recover a login is to e-mail them a one-time link that logs them in automatically and takes them straight to a page where they can choose a new password. Create a prototype and show it in action to them.
Update: we are now starting to see lawsuits and prosecutions against companies that fail to secure their users' passwords properly. Example: LinkedIn slapped with $5 million class action lawsuit; Sony fined 250,000 over PlayStation data hack. If I recall correctly, LinkedIn was actually encrypting its users' passwords, but the encryption it was using was too weak to be effective.
I'm left wondering if any of these requirements mandate a retrievable password system. For instance:Aunt Mabel calls up and says "Your internet program isn't working, I don't know my password". "OK" says the customer service drone "let me check a few details and then I'll give you a new password. When you next log in it will ask you if you want to keep that password or change it to something you can remember more easily."
How is this worse for the less PC-literate than being told their old password? And while the customer service person can get up to mischief, the database itself is much more secure in case it is breached.
I think 1. is the better choice, because it enables you to designate someone within the client's company to hold the private key. Make sure they generate the key themselves, and store it with instructions in a safe etc. You could even add security by electing to only encrypt and supply certain characters from the password to the internal third party so they would have to crack the password to guess it. Supplying these characters to the user, they will probably remember what it was!
795a8134c1