1
$\begingroup$

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.

$\endgroup$
  • $\begingroup$ If you have no database to store accounts, how are you going to distinguish users? Suppose 2 users decided to have user name Alice. Bob established p2p connection with Alice. But how he knows which Alice it is? $\endgroup$ – mentallurg Jan 3 at 23:51
  • $\begingroup$ In fact you can't directly chose your username, what you chose is your password, and it gets hashed and converted into a human-meaningful identifier. For example with tripphrases, you can get something funny like "behold my furious posterior". "Alice" and "Bob" are not usernames but people. $\endgroup$ – JacopoStanchi Jan 3 at 23:55
1
$\begingroup$

You can use a standard signature scheme. The user will type in a password, and receive their private key and associated username. Then, to post a message, they sign the message and broadcast the message, username, and signature. Other users will convert the username to a public key and then verify the signature.

This is the same way that bitcoin handles the identity crisis: tying messages to keys instead of real people.

$\endgroup$
  • $\begingroup$ That's a better way to handle the "identity crisis" (I like your phrasing) than my challenge system, but it still uses public-key cryptography, that I wanted to avoid for my project. But I'm not ontologically against it, so if I don't see a solution that doesn't use public keys I will accept your answer. $\endgroup$ – JacopoStanchi Jan 4 at 0:04
  • $\begingroup$ Can I know why you don't want to use public key cryptography? Signing is a cryptographic primitive after all. $\endgroup$ – theaspirer Jan 4 at 0:07
  • $\begingroup$ It's quite slow (RSA and the like), let alone for a web browser, and I will use js-ipfs for the p2p communication, which already uses a private/public key pair and it would be redundant to have another one. I don't want to use the IPFS public key to generate the identifier, because this key only persists on one browser, so if you want to use your identity on another browser or computer, you have to transport you key on a USB stick or something like that. $\endgroup$ – JacopoStanchi Jan 4 at 0:13
  • 1
    $\begingroup$ Users aren't going to be posting messages faster than their device can sign them. They won't even be able to hit the buttons on the screen fast enough. Most people also probably won't be reading messages faster than their device can verify. If someone wants to take their identity to a new device, they can enter their password again and get their private key right then and there. $\endgroup$ – theaspirer Jan 4 at 0:24
  • 1
    $\begingroup$ I thought you'd have some central server receiving and storing messages which could also give timestamps, but it looks like I was mistaken. Anyways, the protocol is recursive zero knowledge, but someone else very briefly mentioned it to me and I never looked into it. $\endgroup$ – theaspirer Jan 5 at 23:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.