Multiplayer authentication API: Difference between revisions

From Official Factorio Wiki
Jump to navigation Jump to search
mNo edit summary
 
(5 intermediate revisions by the same user not shown)
Line 9: Line 9:
== API endpoints ==
== API endpoints ==


=== <code>/generate-server-padlock-2</code> ===
=== <code>POST /generate-server-padlock-2</code> ===
 
This endpoint is called by the game server once on startup to obtain a public identifier and a shared secret.


==== Request ====
==== Request ====
Line 18: Line 20:
! Key !! Description
! Key !! Description
|-
|-
| <code>api_version</code> || always set to <code>6</code> by clients
| <code>api_version</code> || Set to <code>6</code> in all observed requests
|}
|}


Line 28: Line 30:
! Key !! Type !! Description
! Key !! Type !! Description
|-
|-
| <code>server_padlock</code> || string || Opaque random string, shared secret between game server and auth server
| <code>server_padlock</code> || string || Shared secret between game server and auth server, opaque string
|-
|-
| <code>server_hash</code> || string || Opaque game server identifier
| <code>server_hash</code> || string || Server identifier, opaque string
|}
|}


=== <code>/generate-user-server-key-2</code> ===
=== <code>POST /generate-user-server-key-2</code> ===
 
This endpoint is called by a client when attempting to join a game server.


==== Request ====
==== Request ====
Line 42: Line 46:
! Key !! Description
! Key !! Description
|-
|-
| <code>api_version</code> || always set to <code>6</code> by clients
| <code>api_version</code> || Set to <code>6</code> in all observed requests
|}
|}


Line 54: Line 58:
| <code>token</code> || User auth token, as obtained from the [[Web authentication API]]
| <code>token</code> || User auth token, as obtained from the [[Web authentication API]]
|-
|-
| <code>sever_hash</code> || Server's identifier, transmitted during connection establishment
| <code>sever_hash</code> || Game server's identifier, transmitted during connection establishment
|}
|}


Line 66: Line 70:
| <code>server_key</code> || string || Base-64 encoded user-server-key
| <code>server_key</code> || string || Base-64 encoded user-server-key
|-
|-
| <code>server_key_timestamp</code> || string || Timestamp when <code>server_key</code> was issued, in <code>YYMMDDhhmmss</code> format
| <code>server_key_timestamp</code> || string || Timestamp when <code>server_key</code> was issued, in <code>yymmddHHMMSS</code> format
|}
|}


== User-server-key algorithm ==
== User-server-key algorithm ==


The game server verifies the join by calculating its own version of the user-server-key using the <code>server_padlock</code>, username, and <code>server_key_timestamp</code>. If it matches the <code>server_key</code> transmitted by the client, it knows that it was generated by the authentication server, attesting the validity of the user's credentials.
The game server verifies the join by calculating its own version of the user-server-key using the <code>server_padlock</code>, username, and <code>server_key_timestamp</code>. If it matches the <code>server_key</code> transmitted by the client, it must have been generated by the authentication server (because only it shares knowledge of the server padlock), thereby attesting the validity of the user's credentials.


The algorithm is as follows:
The algorithm is as follows:


1. Concatenate the padlock, username and timestamp strings, separated by underscores.
# Concatenate the padlock, username and timestamp strings, separated by underscores.
2. Generate an MD5 HMAC over the resulting string, with the server padlock as the key
# Generate an MD5 HMAC over the resulting string, with the server padlock as the key
3. Base64-encode the result
# Base64-encode the result


As an illustrative example, using shell commands:
As an illustrative example, using shell commands:


<pre>
<syntaxhighlight lang="bash">
$ padlock=ZjX+YSCEZgdFMVCzLLt8F8NOoWAmAG9WkUwv1dir4gg=
$ padlock=ZjX+YSCEZgdFMVCzLLt8F8NOoWAmAG9WkUwv1dir4gg=
$ username=Xiretza
$ username=Xiretza
Line 88: Line 92:
$ printf '%s_%s_%s' "$username" "$padlock" "$timestamp" | openssl mac -digest md5 -macopt "key:$padlock" -binary HMAC | base64
$ printf '%s_%s_%s' "$username" "$padlock" "$timestamp" | openssl mac -digest md5 -macopt "key:$padlock" -binary HMAC | base64
nV89TIBaIOvwUDQwrdK0/Q==
nV89TIBaIOvwUDQwrdK0/Q==
</pre>
</syntaxhighlight>
 
The game server should additionally verify that the <code>server_key_timestamp</code> is not too far in the past (so leaked user-server-keys cannot be reused indefinitely), but it is currently unknown whether this is done, and if so, what the expiry time is.
 
[[Category:Technical]]

Latest revision as of 22:17, 18 October 2024

Category: Internal API

The multiplayer authentication API allows multiplayer servers (be they dedicated headless servers or games hosted from within a client) to verify that a connecting user is who they claim to be.

An overview of the API architecture is given in FFF-139.

All endpoints are relative to the https://auth.factorio.com/ URL.

API endpoints

POST /generate-server-padlock-2

This endpoint is called by the game server once on startup to obtain a public identifier and a shared secret.

Request

Query parameters
Key Description
api_version Set to 6 in all observed requests

Response

JSON body
Key Type Description
server_padlock string Shared secret between game server and auth server, opaque string
server_hash string Server identifier, opaque string

POST /generate-user-server-key-2

This endpoint is called by a client when attempting to join a game server.

Request

Query parameters
Key Description
api_version Set to 6 in all observed requests
x-www-form-urlencoded body
Key Description
username The player's username, as obtained from the Web authentication API
token User auth token, as obtained from the Web authentication API
sever_hash Game server's identifier, transmitted during connection establishment

Response

JSON body
Key Type Description
server_key string Base-64 encoded user-server-key
server_key_timestamp string Timestamp when server_key was issued, in yymmddHHMMSS format

User-server-key algorithm

The game server verifies the join by calculating its own version of the user-server-key using the server_padlock, username, and server_key_timestamp. If it matches the server_key transmitted by the client, it must have been generated by the authentication server (because only it shares knowledge of the server padlock), thereby attesting the validity of the user's credentials.

The algorithm is as follows:

  1. Concatenate the padlock, username and timestamp strings, separated by underscores.
  2. Generate an MD5 HMAC over the resulting string, with the server padlock as the key
  3. Base64-encode the result

As an illustrative example, using shell commands:

$ padlock=ZjX+YSCEZgdFMVCzLLt8F8NOoWAmAG9WkUwv1dir4gg=
$ username=Xiretza
$ timestamp=240208183717

$ printf '%s_%s_%s' "$username" "$padlock" "$timestamp" | openssl mac -digest md5 -macopt "key:$padlock" -binary HMAC | base64
nV89TIBaIOvwUDQwrdK0/Q==

The game server should additionally verify that the server_key_timestamp is not too far in the past (so leaked user-server-keys cannot be reused indefinitely), but it is currently unknown whether this is done, and if so, what the expiry time is.