[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.

You are right on the fact that hashing algorithms (SHA-1, SHA-256, …) can theorically be retro-engineered unlike asymmetric encryption algorithms (RSA, ECC, …). As this article puts it, hashing algorithms have a lifecycle and eventually become obsolete. What I mean by retro-engineering is to find a trick so that the number of tries needed to get a collision is low enough for a practical attack. And while we cannot find such tricks (with current Turing machines) for asymmetric encryption algorithms like RSA because of a mathematical impossibility (unless P=NP), hashing algorithms are just doing obfuscation using an ever increasing complexity in their working. The only threats to asymmetric encryption algorithms are the increasing computing power of attackers and quantum computing (having a whole other complexity class), but the threats to hashing algorithms are all the threats mentioned before plus retro-engineering. I close the parenthesis.

So yes, I agree hashing a private key can be dangerous in the long run. In fact the tripcode system is not totally serverless even though it doesn’t store accounts in a database. You don’t have any means to check if a certain 4chan “tripfag” (an user with a tripcode) gave the correct secret input that creates this very tripcode, you can just trust the 4chan website. But this kind of system wouldn’t work in a decentralized framework like IPFS because we have no authoritative party.

So let’s forget the first part of my message, tripcodes, but let’s keep the second part, turning a human-meaningless identifier into a human-meaningful one. My idea is to generate a human-memorable tripphrase using the public key. To check that someone really owns their tripphrase identifier, you translate it back to a public key and you compare it to the public key that verifies the digital signature of the message. If it’s not the same, the person is doing a masquerade. This way you have a very strong serverless authentication system without ever writing a password.

And we could still use passwords using this method: a password would be translated into a private key (by being hashed or by simply being converted into binary) that would generate the public key, which would then be converted into a human-meaningful tripphrase.

I have read a little but I am not more of an expert than you, I think selling us the idea of WebAuthn should rather be your responsibility.

I don’t think i fully get your suggestion? Please do tell me more :slight_smile:
Could you provide an example of how it would work?

I just tried this: http://worrydream.com/tripphrase/ and if i follow the logic on that page then i still have to enter a username and a password. Just the public sees “explode my galactic anaconda” that can only be generated with the password i picked. Hence creating a sort of public-private-key logic in a much shorter form. But the user still needs to provide a password! It’s just a clear form for other users to easily see that i actually posted one because of the memorable tripphrase behind my name. So if that phrase suddenly is different but with the same username in front of it then we have someone who tried to take on my identity.

Shit :stuck_out_tongue:

I only find it an interesting concept. I’m not planning to be a WebAuthn ambassador :wink:
I think the idea sells itself if you’ve used it before. I for instance can go to (very few) sites that properly implement WebAuthn where i press login. Then my phone buzzes, i need to login on my phone and authorize the login on that site. It’s one click if i’m already logged in on my phone. It’s two if i’m not (as i have to unlock my phone first). This works with the krypton authenticator. Now that is not exactly how webauthn is supposed to work as you need a krypton browser extension which just intercepts the webauthn calls, redirects it to your authenticator (my phone) where the response is send back over the internet to the site and allows me to login. The pure webauthn authentication would be if i connect my phone via bluetooth with my pc and login that way. But that only works on VERY FEW sites as the specs for that logic aren’t even completed yet. Google has an implementation that works on their sites though, so that’s cool. Regardless of the implementation detail, as soon as you use this for a few sites it’s easy to get used to it and want it everywhere :slight_smile: hence my motivation for asking it. As i’m quite a fan of the ease of use if gives.

Regardless of your suggestion or mine. The thing thoroughly missing in IPFS to make any of it possible is a native implementation for public-private cryptography. Yes, stub implementations can be used… but that only complicates using it.

Ok, currently a tripphrase system works like that:

password --(hash function)--> hash --(exquisite corpse)--> tripphrase

My idea works like that:

private key --(generator)--> public key --(exquisite corpse)--> tripphrase

Note that we wouldn’t use a hash function anymore. The private key given in input of the algorithm could be stored in your phone using WebAuthn (thus having a passwordless authentication system), or it could be obtained from a password as I said.

Verifying an identity with my idea:

  1. tripphrase --(reverse exquisite corpse)--> public key --(decrypt digital signature of message)--> hash of message (?)
  2. message --(hash function)--> hash of message
  3. Compare the 2 hashes obtained. If they are not the same, the person is lying on their identity.

Ok but you’ve just described the “passwordless” part of WebAuthn that is genuinely a good idea and that I reuse in my idea above. But can you explain the “relying party”/“challenge” part?

Ahh, i see.
Your idea won’t work with a phone’s biometric sensors. The private key is “stored” on that individual sensors chips. It never ever leaves the chip. You can only “assign” your fingerprint to that chip. Then you can only verify that your finger (and the public key it in programming has) actually matches the sensor.
The only thing you can do is register all your fingers as they will all have a different public key. Oh, that’s going to give some interesting usecases. You can then login on certain sites with only your middle finger for instance :stuck_out_tongue: (i think i’ve got this logic right, but this too is quite tricky to get right so take it with a grain of salt)

This means that you cannot influence the private key, as it’s hardcoded on the chip.
That in turn means that you have no influence over the generated tripphase i think.

That being said, if you do manage your own private key then it does work as you described.

That’s exactly the part i’ve been asking about before as i don’t fully get it either :slight_smile: