I'm trying to wrap my head around how to exchange user's keys with a server.
Maybe during sign-up a JS applet generates a key-pair for the user. These keys would be used for signing subsequent requests from the user to the server, so the server needs a copy of the users' public key to associate with that user's account.
But sending the public key to the server is subject to MITM attacks - if a sufficiently motivated bad guy wanted to he could put himself in the middle, capture the public key on its way to the server and substitute with a key for which he controls the secret key.
Part of the solution seems to be to have the agent submit the public key only via an encrypted channel, eg TLS. But it seems that with browser based applications, the onus is still very much on the user to be both educated and awake enough to realize when their session is not with the right server that he aught to be connected to. In particular our motivated bad guy could set up something that appears authentic and credible, eg
httpS://certificate_server_acme.com
which he would be in control of. Our user may not realize he SHOULD be connecting only to, eg, httpS://certificates.acme.com
I suspect that this is just a case of "self-signed certificates". Passwords doesn't solve the issue. Verifying a user's key by means of an email message is not viable unless users can compare and verify a key and our motivated bad guy cannot tamper with email messages on the way to the user.
Or is there something, maybe a feature of OpenID, that can be used?