[idea] WebAuthn and IPFS in a truly distributed manner

Hi,

I’ve been thinking about the possibility of creating a truly distributed site in today’s bleeding edge software stack. Everything that requires a single entry point to run form is something i discard, just because that’s the very thing i try to avoid in going distributed.

In lots of today’s “distributed” sites there still seems to be some form of centralized need making it not fully distributed. Now when using web addresses and having one point, a name, to access it is a given. But that should imho be the only “centralized” point of entry.

In this post i’d like to focus on one seemingly tiny but highly important step in going distributed that at the moment just doesn’t seem to be a possibility yet. Or not to me yet, but perhaps i’m totally wrong :slight_smile: .

WebAuthn
If you don’t know what it is, it’s basically the future of passwordless login systems where something you have (your phone, a key, …) proves that you are who you are and allows you to login.
A flow of how it establishes that fact is represented in the image below (stolen from here, read it for a much more in depth article about what WebAuthn is)

As you can see in the image, there is a connection with some service (a relaying party) that hands you a challenge to solve. Overly simplified, if your device returns an answer that can be verified by your public key then you’ve proven to be who you claim you are and are logged in.

If you were to make a website you need to have something running that verifies who you claim you are. You need to have a “relaying party” on your server that takes care of that for you. Now this is where i see some issues with IPFS in it’s current form and this authentication method. This simply cannot be done. Yet. Right?

Relaying party as IPFS service?
As you can see above, “something” needs to generate random data. That “something” also needs to verify your response. Those two things can’t be done in a static environment, which IPFS is. The only way i can see this being possible is having some flag in IPFS to enable a “relaying party” service (much the same way that you can also turn pubsub on to be part of that network). This in turn means that not only “i” can verify, using the relaying party, that i am who i claim to be. But anyone with the relaying party flag turned on should be able to. Thus in effect creating a distributed relaying party network. This implicitly also means that my public key must known at any given relaying party. Now, that might be as simple as “ipfs relay-party verify <challenge> <cid>” where to cid would point to a file that would be my public key. The challenge could also be a cid pointing to a file.

Authentication in IPFS?
So how would one go about authentication on IPFS? Preferably in WebAuthn. But we can take this concept to be more abstract. In it’s core functionality i need to be able to prove that i have the key i claim to have which the other can verify with my public key. This is basically Public-Private Key Cryptography. But how does one apply that logic in IPFS to create an actual authentication system? I can think of a few ways.

#1 IPFS <crypto> command?
No, there is no such command :slight_smile:
I looked over the manual and there don’t seem to be any cryptography options in the IPFS cli. But then again, would that be needed, like, at all? There are whole javascript libraries out there that can do the encryption. So when going for a authentication framework, that might be the way to go?
On the other hand, having build in crypto solutions in IPFS does allow for the basic functionality to be provided from IPFS as opposed to javascript libraries.

#2 authentication framework inside IPFS
This is very much related the above one. Only then focused on authentication specifically where IPFS would support a few that can then be used in a fully distributed manner. It could still be something like ipfs auth webauthn <challenge> <public key> … I think this would be rather specific. It might work for as long as the (in this case) webauthn standard lives, but would need to be updated over time. It might also complicate looking at sites via IPFS gateways where one gateway might have a newer authentication protocol then another one. Leading to a mess you probably don’t want.

So,. just throwing this out here to see if there are more opinions on this.
Remember, the eventual goal is a fully decentralized authentication or the raw components to make that!

Cheers,
Mark

1 Like

Hello markg85,

good subject i’m very intresting by this subject currently. you define the context and your subject is very clear.

I agree with you that decentralized authentication would be very useful for IPFS. For that I follow some project and this moment :

1 : https://github.com/jonnycrunch/ipid & https://github.com/ipfs-shipyard/js-did-ipid
2 : https://github.com/CleverCloud/biscuit (jwt / macaroons / vanadium)

let me know your opinion on that.
Regards

Hi,

Now DID makes sense to me. Thank you very much for sharing those links!
That’s an interesting read!

It does look like DID is what i’m talking about but i’m not quite sure how that relates to WebAuthn. Like, is it an “alternative” to it? Or is it a base functionality on which you could implement WebAuthn?

I’m asking because it would be rather nasty if distributed apps required X way of authentication (lets say DID) while the good old web required Y way of authentication (say WebAuthn). I think that’s a situation you’d want to prevent.

I don’t fully get IPID yet, but from the looks of it thus far i think it does it all in the browser. They include libp2p-crypto which i assume is then run in the browser. It seems to be a way to verify that if a have a private key, i can let that system know with certainty that i am who i am. It does not seem to allow the option to integrate with, for example, biometric devices. But then again, i could see DID as a more abstract version where something build on top of that then can add in the biometric part.

I havent looked into detail at biscuit yet. I don’t get how that one works.

I’d love to get more opinions on this and the initial post :slight_smile:

Cheers,
Mark

If I’m not mistaken, symmetric and asymmetric cryptographies will be implemented natively on IPFS at some point, so for the time being you can use the Javascript libraries as polyfills. In order to implement WebAuthn, you also have to implement direct communication between 2 nodes in IPFS because it’s not the case right now.


For serverless authentication, an alternative to WebAuthn is tripcode systems, already used on some imageboards (4chan, Futuba, …). When you “login”, you enter your password and it gets hashed into a digest (or hash) that is your identifier. But the problem with usual tripcodes (and WebAuthn for that matter) is that the identifiers are not very memorable for humans.

So if you want to go a step further and have human-meaningful identifiers, you can do one of the following:

  • Take the digest and use it to create a profile picture with Gravatar (the default profile picture generator of GitHub and Stack Overflow).
  • Take the digest and use it as an input to a neural network that creates profile pictures (examples with people and animals, landscapes would be cool too).
  • The 2 precedent solutions are not very satisfying because you can’t fetch an user using their profile picture, you can only use character string identifiers. You can create one of those using Proquint Pronounceable Identifiers, and the good thing is that it is natively supported in IPNS. For example "MyPassword" --(CRC32 hash)--> "7d586a02" --(Proquint)--> "hotig-muhig-donig-fubag". The hash function is totally arbitrary of course.
  • Finally, my favorite solution is tripphrases. Basically, you turn a digest into a human-meaningful (and sometimes very funny) phrase using the exquisite corpse method. For example "MyPassword" --(tripphrase)--> "interleave my calcifugous ghost".

This way every user has a recognizable and unique identifier. That’s kind of a hack to Zooko’s triangle even though it’s not really a proper counter-example.

Using one of the methods I listed before, there’s no need to involve a third party during authentication, like a relying party with WebAuthn. Speaking of relying parties, what would be the incentive to do their job? Besides, in the case of WebAuthn, only the relying party knows you are authenticated, but all the other users don’t. So every user has to become a relying party and send you challenges in order to authenticate you? But what is the point of doing that if you can just use digital signatures on your messages to prove you’re you?

Anyways thank you for the quality post, I’d like to see more like these on this website.

Any word on when hey plan on integrating that?

Ha, lol. That “tripcode” is the exact opposite of what WebAuthn tries to do. The former tries to make structure in a password making it complex to hack and simple to remember. The later tries to get rid of passwords altogether. I’m on the bandwagon of the later :slight_smile:

Hmm, good one!
I’m just guessing here, but isn’t the idea of that relaying party that i can confirm over and over again (with any data thrown at me) that i am who i claim to be. The verification now is dynamic. As in, it’s verified with a different random string every time. I suppose that’s an added security measure. But i can’t really think of a way to be more insecure if you have a static authentication… I must be missing a point there :slight_smile: Could, in a static logic, the response be cached and be abused that way?.. Just guessing…

Well, what’s the incentive for people the be in the pubsub network? If you’re not using it, there is none.
I suppose the same is true for the relaying party. It’s good to have it spread as broadly as possible, but people could (should?) opt to disable it if needed. For example on highly constrained devices like IOT where you might want to have to authenticate to something but not want to help others out to get them authenticated. That seems like a valid case.

Note, just having the public-private logic in place without WebAuthn would already open up a whole lot of authentication possibilities that just aren’t there now. Well… they are if you use stubs but then you are definitely limiting IPFS in this regard. Sure, stubs can be found everywhere… But i remain of the idea that the very basic building blocks should be in IPFS native.

Thank you for the kind words :slight_smile:

Sorry I have no idea, maybe there is a roadmap available you can check out.

With tripcodes, the input given by the user has to be a private information, it can be a password but it can also very well be your private key. For example, you give your private key and you get the tripphrase “behold my furious posterior”.

We can still use the “passwordless” aspect of WebAuthn (i.e. carrying your private key in your smartphone for instance) in a more efficient authenticating system in my opinion.

If an attacker wants to forge messages signed by you, he has to find your private key. As soon as he finds it, it becomes as easy to deceive the authentication 1000 times than it is to deceive it once. A dynamic verification as you call it is not more secure than a static one.

There are 2 possibilities:

  • Everyone has to authenticate everyone, zero trust: in this case everyone is a relying party and the incentive to be one is just to be sure that the person you’re communicating with is the person they claim to be. I find this system less efficient than digital signatures though, because it is proactive and not reactive (you have to send challenges to everyone). Besides you can send a challenge to someone, they validate it, and if you receive a message that you believe is coming from them, if it is not signed it is not secure at all and all the previous authentication was for nothing.
  • Relying servers are some sort of trusted third-party: if a relying party has already authenticated you, other people can trust you without doing all the process of authentication again. In this case we have to find an incentive to relying parties. You could say the relying party feature would be ‘opt-out’ (i.e. if the user doesn’t say explicitly that they want to disable this feature it is enabled), but it doesn’t solve the issue of authoritativeness for relying parties, how can we trust them? No really, I can’t figure the point of relying parties, maybe I should read the WebAuthn documentation.

I agree with you on this.

Never EVER do that! It’s destroying the whole public PRIVATE key principle.

So if that’s right, then there doesn’t need to be a “relying service” at all, just being able to verify a public key belongs to the one that contacts you would be enough? That seems like a much easier system to me :slight_smile:

Yup, you should read it :slight_smile: But it’s still not easy to get it… I don’t fully get it either.
In fact, i hope you could read it and perhaps clear that part up a bit as i struggle with it too.

Why? The private key would still be unknown to other people because it would get hashed first, and then it is translated into a phrase using the method described. Hash functions are one-way functions so it would theorically be impossible to reverse engineer the private key using its hash.

Edit: Ok upon rereading my message it was not very clear, when I said you give your private key, I meant you give it to the tripphrase generator not other people.

Yes, IMO digital signatures are more than enough. I will dig deeper into WebAuthn though.

Still a big no imho.
In general, you should never use the private key for anything else besides encrypting or signing data.
If you do, even in one-way-hashes, you risk them being compromised sooner or later. Remember, hashes have collisions. Hashes that are deemed safe now will probably be weak in 10 years. They don’t need to even figure out a way to extract your original data, if they can use a second input that gives your exact hash (aka, a hash collision) then they are in too.

Anything that exposes the private key to the outside is a big no-go for me.

Did you? :slight_smile: I’m just curious what your opinion on those relaying services is as i don’t fully get it.