I want to do a completely serverless p2p chat application on web browsers, so it won't even have a database to store accounts, but I still want to have some kind of identity system on it (an user can have a username on this chat that only they can use). To achieve this, I began to work on an authentication system a bit reminiscent of tripcodes, used on various imageboards (I don't know if this is really the way to go, I'm open for new suggestions):
- the user types a password,
- the application generates a public information (e.g. a hash or a public key) from this password using a one-way function,
- this public information is then converted to a human-meaningful identifier using systems like tripphrases, proquint or identicons.
Examples:
"MyPassword" --(CRC32)--> "7d586a02" --(proquint)--> "hotig-muhig-donig-fubag"
"MyPassword" --(MD5)--> "48503dfd58720bd5ff35c102065a52d7" --(tripphrase)--> "interleave my calcifugous ghost"
The problem with using hashes as identifiers in a p2p system (i.e. with zero trust and no central source of truth) is that nothing prevents some user to write messages using whichever identifier they want while pretending that they obtained this identifier by hashing their password locally, like the protocol says. Thus, what I want is a way to prove the ownership of an identity without revealing the password. I can only think of one way to solve this problem:
- Alice types a password,
- the application derives a private/public key pair from this password,
- the public key is used to generate the human-meaningful identifier of Alice,
- Bob wants to verify the identity of Alice:
- Bob sends a challenge (i.e. a random number) to Alice,
- Alice encrypts the random number with her private key,
- Alice sends the result back to Bob,
- Bob decrypts the result using the public key of Alice (it can be obtained by converting Alice's identifier back to a public key),
- if the decrypted number is the same than the one previously sent, then Alice indeed owns the password, otherwise Alice is lying on her identity.
But I would like to know if there is a simpler protocol than that to solve my problem. Preferably, I would like to avoid public-key cryptography altogether. As I'm doing this project just for fun, I don't really care about the following points:
- the strength of the passwords,
- if two users use the same password and hence get the same identifier,
- if other people know the hash or associated public key of a password, which clearly gives out information on the secret password, so a zero-knowledge proof is not necessary.
Any idea?
Thank you for your help.