Cubyz icon indicating copy to clipboard operation
Cubyz copied to clipboard

Authentication without a central authentication server

Open IntegratedQuantum opened this issue 4 months ago • 36 comments

Design Goals

  • Clients should not be able to impersonate other clients (and gain access to their character/inventory).
  • Servers should not be able to silently relay the login process to gain a session on another server

Preliminaries

  • Each player has a public/private key pair. Ideally these are presented to the user as a seed phrase, so we always have the option to switch seamlessly to a new algorithm in case the old algorithm got compromised.
  • The protocol should use some form of encryption past the initial key exchange to avoid a man in the middle from tampering with the packets once the session is established

Login Process

  • The client sends its public key to the server
  • The servers uses the clients public key to encrypt a challenge, the encryption type and a key for the remaining encryption process.
  • The client decrypts the message and sends the challenge data back to the server (using the now encrypted channel)
  • The server decrypts the data and uses it to verify the client's ownership of the public key
  • The server then uses the public key to look up the player data, if it doesn't exist yet it creates a new file

Limitations

  • Obviously a man in the middle could still hook into your connection, however it would be impossible to do so without providing a different public key, so the original account is not under attack. Of course if an attacker were to do this over a long period of time, then they could take over your account eventually, but it seems unreasonable to do this in a block game, so I don't think we need to worry about it.
Old proposal To my surprise it seems like this is actually possible

Design Goals

  • The client should be able to log in with a single password and username(or another identifier, to be decided) to all servers
  • A malicious server must not be able to steal your credentials

Registration

  1. The client sends its username/id to the server
  2. The server creates a new private/public key pair for the username/id and stores them in the player file.
  3. The server sends the public key to the client
  4. The client generates a new password for this particular server
  5. The client stores its password alongside the server public key and encrypts them using the player's password
  6. The client sends the encrypted password+public key back to the server
  7. The server stores the encrypted password+public key in the player file
  8. The client logs in using the method below

Login

  1. The client sends its username/id to the server
  2. The server looks up the encrypted password+public key using the username/id and sends it to the client
  3. The client decrypts the per-server password and public key using the player's private password
  4. The client now encrypts the per-server password with the server's public key, note that only the real server can decrypt the password.
  5. The server decrypts the password computes a hash and compares it with the stored hash, if no hash is stored yet (because we are in the registration process) it stores it now.

Remaining problems

  • The server knows the public, the per server password and knows the player-password encrypted version of these. Together this may be enough to brute-force the player's password. → A sufficiently secure encrpytion algorithms needs to be used to prevent this.
  • If a malicious server relays this handshake to a target server, then it can steal your account for a session there. → A solution could be to send the IP the client connected to alongside the per server password in step 4. This would allow the server to identify if the client directly connected to it or chose an indirect path.
  • If the world is shared with other players, then the per player private keys would be public. This would allow a malicious server to decrypt your per-server password, allowing them to join the original server. → It would make sense to store the private key somewhere separate from the world itself to still allow world downloads. Furthermore a mechanism to re-register a player on the world copy is needed.
  • Anyone could create a new account under your username/id on a server and you wouldn't be able to claim it back → I don't think this is even solvable. It would be rather annoying to the player if this happens, but they could just change their name in that case.

Sources

I took some inspiration from http://www.peerson.net/papers/passwordsP2P.pdf

IntegratedQuantum avatar Aug 04 '25 16:08 IntegratedQuantum

Anyone could create a new account under your username/id on a server and you wouldn't be able to claim it back → I don't think this is even solvable. It would be rather annoying to the player if this happens, but they could just change their name in that case.

This is an advantage and disadvantage at once. On one hand it means someone can claim your username (but you can always choose a different one), but on the other hand it means that you can't globally claim rare usernames and sell them. Additionally as practice shows usernames most likely to get stolen (streamers, internet celebrities) are also ones which are most likely to change their usernames often to NOT get recognized.

The problem I see is that they can't just change their username if they are playing with this one on different servers, or they will lose all their stuff, they even may run into more conflicts, which means they may claim even more names before they find one that is not used on any of the servers they play on. That sounds like a very bad cycle.

To solve the inconvenience part of the problem we could just add server list with username configurable on server basis with global username being the default.

However problem of claiming multiple usernames is much harder to solve, rather impossible without external authority like phone numbers or emails

Argmaster avatar Aug 04 '25 16:08 Argmaster

We could have display names separate from usernames, but that might be over complicating things.

codemob-dev avatar Aug 04 '25 16:08 codemob-dev

Why does the public private key pair have to be per player?

Argmaster avatar Aug 04 '25 17:08 Argmaster

We could have display names separate from usernames, but that might be over complicating things.

That unfortunately has some other implications. To avoid situations where players on the servers are pretending to be someone else then they are you would have to display both and this creates UI challenges both for chat and for user name labels. For PvP servers it's a difference between life and death.

Argmaster avatar Aug 04 '25 17:08 Argmaster

Why does the public private key pair have to be per player?

It might not be strictly necessary, but if it is global then it could be brute-forced, allowing you to decrypt the per-server player password of every player, if you get access to the encrypted version. However if it's per player, then you cannot brute force it, since you only know it if you intercept the initial registration.

IntegratedQuantum avatar Aug 04 '25 17:08 IntegratedQuantum

What if we used Sha 256 hashed nanosecond timestamps of when the game was first run as player names? Ofc we would communicate to the player "hey, it's your identity, save it or you will lose all your shit". Then we would display only first few hex digits, as many as necessary for it to be unique on that server (like git) + display name. Basically a tag. How hard is it to have same nanosecond timestamp or Sha 256 as someone else? This is only for the display name problem ofc. If someone steals it it kind of sucks, but there is still password to cover your existing accounts. It's just a tiny bit better than copying whole server list.

Argmaster avatar Aug 04 '25 17:08 Argmaster

Actually I think we should just keep it at names. Sure renaming is a bit of a pain on servers you are already active on (you need to log on with both and swap over your inventory and fix up all the totem permissions), however I think this is better than using random ids since it easy to forget about them. Especially since it is kind of unusual for games to use a random id like this.

Furthermore if someone does steal your ID then it is rather difficult to change it and remember which one to use for which server.

It is much easier to remember names, and name variants, in the worst case you may just need to go through your aliases in order and try them all until one gets accepted by the server. Nowadays people do seem to have many names already, since on many platforms you cannot choose the one you like.

IntegratedQuantum avatar Aug 04 '25 17:08 IntegratedQuantum

As we already discussed in discord, there is no way to change master password after it's set. Since the name is claimed you are no longer able to re-claim it. Sure, there are plenty of good practices regarding passwords which would reduce the likelihood of this problem, but the whole problem with passwords comes from the fact that people don't follow those guidelines.

What about clean installation/ hardware change? Will it be possible to re-claim your accounts only knowing your password?

Argmaster avatar Aug 05 '25 18:08 Argmaster

What about clean installation/ hardware change? Will it be possible to re-claim your accounts only knowing your password?

Yes of course, that's why the server password is stored on the server.

IntegratedQuantum avatar Aug 05 '25 18:08 IntegratedQuantum

The server knows the public, the per server password and knows the player-password encrypted version of these. Together this may be enough to brute-force the player's password.

Maybe instead of hashing the player's server password we can use another private/public key pair, this would mean the server only knows the public keys (which could be encrypted again with the private key) and not the full contents of the encrypted data, and thus cannot perform a plaintext attack.

IntegratedQuantum avatar Aug 05 '25 18:08 IntegratedQuantum

Quick interrogation, I can see in the registration process, at step 4, that in addition to the username/password, the client should keep a per-server password. In a case where I'm playing on another computer, with the same username/password credentials, and the server has already an entry for my credentials, but I don't have the server password on disk, what would happen ?

Fabccc avatar Oct 12 '25 13:10 Fabccc

the per-server password is stored encrypted on the server.

IntegratedQuantum avatar Oct 12 '25 13:10 IntegratedQuantum

I'm interested in the reason for pushing against a central auth server. It would undoubtedly be the simplest and likely most secure approach.

The immediate idea to come to mind if you yourself don't want to host a central auth server would be to have a federated auth server that multiple individuals can spin up themselves, then allow server hosts to select which auth server they want to abide by. As more servers join the federation the username pool is synced and hopefully an organic auth network is formed. Then in the event someone doesn't want to opt into that network comes along they can either spin up their own without federating or default back to username authentication.

Not a perfect solution, but I have to imagine there are already existing tools that could facilitate this approach.

ThomasJRyan avatar Oct 13 '25 23:10 ThomasJRyan

I think it would make sense to do about the opposite:

  1. The client has a public/private key pair (in separate files, like ssh keys).
  2. The client sends its public key to the server. This functions as the unique identifier for the player (instead of the username).
  3. The server sends some string to encrypt to the client
  4. The client encrypts it using its private key and sends that back
  5. The server verifies it with the public key that was sent
  6. The server now knows for certain that the client has access to the full keypair

This also lets us make allowlists. Simply put the public keys or hashes of them in a file on the server, and only those people are let in! Along with that, it has the advantage of being cryptographically secure and not dependent on a likely insecure password. The player would, to use their account across devices, have to simply copy the keypair from one device to the other. We could have files for that that the game lets you easily export and import ("Export account", "Import account").

TudbuT avatar Oct 14 '25 01:10 TudbuT

@TudbuT public-private key pair has a drawback of being easily lost by non technical players and cannot be remembered unlike the username-password pair. This system is also prone to man in the middle attacks, which is nothing new honestly. Unfortunately this is the case for every authentication you perform with your system. It means that connecting to a malicious server at any point will allow bad actor to authenticate to any of the servers you have joined previously.

But honestly, when I am reading it now, after a few months it is kind of crazy what kinds of weaponry we are considering for a video game where the most valuable thing you can lose is a stack of virtual amber and the most likely bad actor is a 15yo saying bad things in chat and wanting to do mess with his 13yo friends in server.

Argmaster avatar Oct 14 '25 02:10 Argmaster

@Argmaster

It means that connecting to a malicious server at any point will allow bad actor to authenticate to any of the servers you have joined previously.

my proposed solution is not in fact vulnerable to this due to steps 3 and 4

TudbuT avatar Oct 14 '25 06:10 TudbuT

To add to @TudbuT's approach, my two cents:

  • Username/password pairs are easy to understand.
  • It gets confusing if they are unique per-server.
  • It gets more confusing if there's also a server password.
  • Connection details are (also) easy to forget / lose.

See Luanti as an example. This could be solved with good UX, but the complexity is still there.

Proposed UX for a public/private key oriented solution:

  • Launch the game for the first time.
  • "Multiplayer" button is grayed out.
  • Hovering over it shows a tooltip that an "identity" must be created.
  • There is an "Identity" button in one of the corners.
  • Next to it, player model/head could be displayed.
  • Clicking it leads to another screen / opens a popup.
  • Here you can "Create New Identity" and "Import" as well as "Open Folder".
  • Optionally, identities should be able to be protected by a password.
  • Once an identity is created / selected, you can also customize your name / appearance.
  • You can switch between identities, "Export" and "Delete" (with warning).

With the right information on screen, such as displaying a filename, this should make it straight-forward enough for people to understand that their identities are tied to the files. Servers could (by default) lock in the first seen username (minus color codes) so changing them is only possible with admin permission. Similarly, lost identities could be recovered by letting the admin move player data between identities easily – could be as easy as renaming a file storing the per-player information.

Issues like ban evasion will have to be dealt with by tooling, whitelists and vetting people beforehand. A central account registry will hardly help. Malicious actors can likely create tons of accounts either way, as long as it doesn't require payment information. A central place to create and register accounts could, as already mentioned, also be taken down via DDoS, preventing everyone from playing. Hosting it would also cost the developer, require maintenance and potentially moderation.

copygirl avatar Oct 14 '25 07:10 copygirl

I'm interested in the reason for pushing against a central auth server. It would undoubtedly be the simplest and likely most secure approach.

Mainly I just want to have a system that doesn't depend on outside actors to keep their server up. This is also true for a federated network, if the server your name is on gets shut down (or shut out by the server owner) for whatever reason, then the player cannot join.

It might be easier to implement yes, but could you explain why you think it's more secure?

IntegratedQuantum avatar Oct 14 '25 17:10 IntegratedQuantum

I also have an alternative solution that is largely as secure as the keypair solution while remaining username/password based: just hash the username and password together and generate a private key from that hash (it should obviously be a hash made with a good, that is hard, hashing function). this is still low entropy due to relying on the user like that, but it solves the UX issue of moving keypairs between computers.

this is merely another solution i could imagine btw, not necessarily something i would prefer over proper keypairs as proposed by @copygirl

TudbuT avatar Oct 14 '25 20:10 TudbuT

I'll need to think about the exact approach some more.

I do thing maybe associating the account with a private/public key pair instead of a username+password may not be that bad actually. We just need to make it easy and obvious how you would share it between devices and stuff. And it would certainly simplifies some stuff.

IntegratedQuantum avatar Oct 16 '25 20:10 IntegratedQuantum

Agreed, if we wanted to we could even put it in a password-encrypted file.

codemob-dev avatar Oct 16 '25 20:10 codemob-dev

It might be easier to implement yes, but could you explain why you think it's more secure?

Secure from the perspective of a user. They (as far as they'll ever be aware) can trust that the central auth server provided by the developer will always be there. Obviously it's only as technically secure as you're willing to make it, but from a user perspective a single source of truth provided by the maintainer is that safest thing.

This obviously does not apply to the federated option and was mostly just an idea that came to mind.

Adding yet another idea you'll not like because it's an outside actor's server: Github App auth is easy to implement, secure, and fairly reliable

ThomasJRyan avatar Oct 16 '25 20:10 ThomasJRyan

@ThomasJRyan What you're saying is simply not true. The cryptographic approach will be both available practically forever and be safer than something that has to be built, maintained and paid for by humans. The only thing that would even begin to make a central auth server "safer" for users if there was some form of vetting of who could create new user accounts. Such as through requiring payment.

copygirl avatar Oct 16 '25 23:10 copygirl

I need to get better at explaining myself. I don't mean safer in terms of cryptographic safety. I mean safer in terms of reliability.

Having to export a key to switch devices opens up the potential for people to lose their accounts. It puts the onus on users to ensure they're making a backup which cannot be taken for granted.

A central auth server provides safety for the end user because it will always (ideally) be available.

ThomasJRyan avatar Oct 16 '25 23:10 ThomasJRyan

Passwords can be lost just the same. Then we need to think of a password recovery function, so we need user's emails, and the ability to send out emails, and probably have to deal with things such as GDPR and similar.

Meanwhile, my suggested solution for lost identities is allowing server admins to manually (and easily) move player data to your new one. Simple, straightforward, and if you got whitelisted (say through Discord or so), then you already have the ability to prove you're the same person.

copygirl avatar Oct 16 '25 23:10 copygirl

Oh that reminds me, you can auth with Discord too

ThomasJRyan avatar Oct 16 '25 23:10 ThomasJRyan

Passwords can be lost just the same. Then we need to think of a password recovery function, so we need user's emails, and the ability to send out emails, and probably have to deal with things such as GDPR and similar.

Meanwhile, my suggested solution for lost identities is allowing server admins to manually (and easily) move player data to your new one. Simple, straightforward, and if you got whitelisted (say through Discord or so), then you already have the ability to prove you're the same person.

that makes sense, and in that case we can just use keys

TudbuT avatar Oct 17 '25 00:10 TudbuT

RE: Recovery methods for asymmetric keypairs:

Many password managers/Crypto wallets/etc utilize recovery phrases. Usually comprised of a series of seemingly random words.

When generating a new identity, we can prompt the user to save the recovery key and disable the acknowledge button until they confirm with a checkbox or something that they've saved it somewhere secure. (Like a password manager, or just an external drive, or something.)

I think this would give us a great balance between usability (enter the recovery key/phrase/whatever to regenerate that identity on a new machine) and security (high-entropy asymmetric keys rather than low-entropy user-provided passwords).

We should also encourage the user to set a password to encrypt the key with, and perhaps give the option to not encrypt it but make it very clear that it's not recommended. (I hope it's obvious why we should guide users against unencrypted storage of a private key, but I don't expect the users to understand intuitively).

BoySanic avatar Oct 17 '25 02:10 BoySanic

This isn't actually strictly related to #1737 but if we did implement a keypair account system, I can imagine if tools might have a createdBy player association. So that others can look at the tooltip and see who made it.

If we did go with keypairs, this would become quite easy to definitively accomplish. We would in some fashion "sign" the item with the user's private key, and others can verify it was them with knowledge of their public key.

Maybe if a client hasn't seen that person online before, and they pick up a tool, it says "created by ????? on 2025-10-16" on the tooltip. Once you see them online again, or when you're within proximity of them, that display name updates to the player's actual name.

It could also just be done with the player's name alone, but something about the absolute "this particular identity created this item" sounds cool to me.

BoySanic avatar Oct 17 '25 02:10 BoySanic

I updated the post with a new method based on a private/public key pair for the client. Please comment if you find any issues with it,

IntegratedQuantum avatar Oct 17 '25 17:10 IntegratedQuantum