I had a wonderfully silly idea yesterday.
Almost all the computers I use on a regular basis are now accessed through SSH public-key authentication; so I type a passphrase into my agent once when I log in, and then get one-touch authentication to practically every other system I need to use. Very nice.
There's one exception, which is Monochrome. The only way for me to log in to Monochrome is using an actual old-fashioned password. Occasionally it annoys me that this one exception still exists, since everything else behaves in such a civilised manner these days.
I could, of course, simply store my Monochrome password in a disk file on the machines I usually log in from, and write some expect-style twiddlings to feed it to Mono when I connect. The expect side of this mechanism is the boring bit; what concerns me is that storing a password in a disk file is generally one of those ‘good god man don't do that’ sorts of practices which make security engineers shake their heads sadly. Now I could have simply decided that my Mono account is non-critical and hence can stand that level of risk; but it didn't feel like a good answer to my gut instincts.
Yesterday I hit on what seemed to me to be a surprisingly reasonable answer. I store two small disk files on two completely different Unix boxes; each one contains eight bytes of random data, related in such a way that the bitwise XOR of the two files produces my password. There is no direct trust path between the two machines (that is, there certainly isn't between my accounts on the two machines, and I don't think the machines have any other users in common). So an attacker breaking into either machine gets a file full of random data which is literally a one-time-pad encryption of my password – so they have literally no more information about what the password is than they'd started with. Only if an attacker can separately break both machines can they get both fragments and reconstitute the real password; and since the machines are completely unrelated except for having one user in common, it seems reasonably unlikely that an attacker would happen to want to hit both those machines in particular.
So an attacker on either machine can't get any information towards my password; but I, sitting on any client box whose SSH agent has been loaded with a key that both machines independently trust, can log in to Mono effortlessly. I think that's rather neat.
(Of course, an attacker on one machine could plant Trojan attacks; often I log into Mono directly from one of the two machines in question, so an attacker hitting that machine could trojan my password retrieval script and wait for me to supply it with a valid SSH key. But then, that attacker could have simply trojanned my SSH client and waited for me to type the password into it, so I actually don't think I've reduced my security level in that way at all! The only plausible additional threat I can think of is that someone walking up to my unattended client box can now access my Mono account trivially, and that's the one thing you have to be willing to accept if you're going to use one-touch authentication in the first place.)
For reliability, you'd probably want to switch away from my simple one-time-pad mechanism to something more like a threshold scheme: cache (say) ten password fragments on independent servers, and arrange that (say) any five can reconstruct the password but any four give no information about it. That way you're protected against a few of the servers being down or unreachable at any given moment, which is probably helpful in practical terms.
Querying the servers using (securely authenticated) UDP is probably a good plan too; if you only need half of them to respond, then reliable delivery doesn't matter to you all that much, and it means it's very easy to send out ten requests and then wait until you've got five responses back, thus taking only one RTT for the entire process (unless you only get four responses and have to re-send, but that'll be uncommon). Much faster than TCP, and orders of magnitude faster than SSH!
The interesting question is whether anyone could run a public service doing this sort of thing. Technically it's all easy enough on the server side (though funnelling the reconstituted password into custom weird-ass client software will always be a painful client-side headache): a bunch of independent organisations each run one server, and a user picks ten of them and uploads a password fragment to each. But the trust issues are the fun bit: how does the sysadmin of each server assure its users that it's genuinely independent of the others, and isn't colluding with them to reconstruct a whole lot of users' passwords?
Perhaps the answer there is for the client to hold the final vital piece of the password. (In fact that ought to be a genuinely vital component, not just another cog in the threshold scheme; perhaps it's the one-time pad that decodes the final output from the threshold scheme.) Then even if all the server admins colluded, they couldn't reconstruct your password between them. (They could collude to create trust paths between their servers, which would reduce the difficulty of an attacker collecting all your pw fragments, but this wouldn't be of direct benefit to the admins themselves so there'd be no incentive for them to do so. I think.)
This is starting to sound disturbingly plausible, in fact! I've almost convinced myself it's a viable business opportunity. I expect it would only be of interest to a few hyper-paranoid security geeks like me, though, so there wouldn't actually be any profit in it :-)