Hash Authentication Design
Hash Based Authentication Design
This document describes the interaction between three entities: the game client with the player who wishes to authenticate, the game server the player is currently playing on, and the authority, in charge of checking the player's identity. We only care about the high level interactions here; the details of the communications are left out (game client and server communicate over the game internal network protocol, game server and authority communicate over HTTP).
We are currently using the hashing algorithm md5 which transforms a data block of arbitrary size into a 16 byte hash value. The operation of md5 is simply denoted with "hash = md5(data)". With "+", we denote concatenation of data blocks to larger data blocks; strings are to be interpreted of data blocks containing the latin1 encoded characters and do not include the C-style trailing 0.
The protocol works in different phases.
Phase 0: Before all that
Already before the client starts the authentication process, it transmits a list of supported authentication methods (hash shemes) to the server. This happens right when the connection is established. Clients not sending the list will be assumed to be old clients supporting the "bmd5" hash scheme only.
As the server logs in to the master servers, it gets told what its public IP address is.
Phase 1: Client requests authentication
The authentication process is usually started by the client (a modified server is allowed to skip this step, if, for example, authentication is to be required to even be on the server). There are two possibilities: The player issues a special chat command: "/login" for logins with a default identity transmitted earlier/a local server account if no default identity has been transmitted, "/login authority" to log in to a selected authority, or "/login user@authority" to log in as a specific user. Alternatively, there is a special login message containing the user name and authority the player wishes to authenticate with. Such a packet is sent by clients that support it via the game menu "Authentication" button.
When the server receives the client's authentication request, it contacts the authority and queries the list of supported methods. From that, its own list of supported methods and the list from the client, the server then selects the best method. It queries the authority again and fetches a list of additional parameters for the selected method.
The server then generates a random 16 byte wide salt data block and transmits the salt, the selected method, its parameters and the username back to the client. A menu title message is also transmitted.
The authority has the potential to return additional information to the verification of a user/password pair. "Blurbs" are currently understood by the server in a very basic form, but are essentially unused. There are proposed blurbs to be understood in the next revision of the armaauth protocol, specifically to increase the potential ability of the role of authentication server as a means of logging into Armagetron related websites.
Phase 3: Client collects password
Upon receiving that information, the client starts a password entry menu, where the player can change his username one last time and enter the password. While that menu is active, keypresses are scrambled in a potentially running debug recording. Then, depending on the selected method, different scrambling techniques are used:
The client calculates
prehash = md5(password + "\0") hash = md5(prehash + salt)
"\0" is a single byte of value 0. Obviously, it's there because of an error in the old implementation, but now we're stuck with it.
This method has two parameters, a prefix and a suffix. Before they enter the scrambling, the sequence "%u" in them is replaced by the username the client entered. Before the password is scrambled, the salt gets scrambled by
salt2 = md5( md5(salt) + md5(serverIP))
where serverIP is the string representation of the server's IP address and port. Then,
prehash = md5( prefix + password + suffix ) hash = md5(prehash + salt2)
In both methods, the resulting hash value is then sent back to the server, along with the value of serverIP used for scrambling the salt (only on post-0.2.8.2.1-clients) and the possibly modified username.
Phase 4: Authentication request
The server checks whether the serverIP value sent by the client matches the IP it was told by the master servers earlier or retrieved by other means. If it does not match, an error is returned to the user immediately. The server then transmits the following data to the authority: - the selected method - the user name - the salt value for the bmd5 method/the salt2 value for the md5 method, calculated on the server using its known IP - the hash value returned by the client
The authority then has to check the password for correctness. Usually, it will have the value of prehash pre-calculated in its database, but it can also choose to calculate it on the fly from a plaintext password (plaintext passwords would increase the network security as they would allow periodic changes to prefix and suffix strings, prehashed passwords make loss of the database less of a problem). Either way, the authority just checks whether a) the user exists and b) hash is the correct md5(prehash + salt(2)) value. The result of the comparison is reported to the game server, which then either reports an error to the client and player or accepts the authentication.
- With the bdm5 method, badmins runnig a server can steal player logins; as a player logs in on their server, they can instead abuse the system to imposter that player on a different server. the md5 method has some protection against that in the form of the server's IP the client entangles into the hash.
- No strong encryption is used. A badmin that has the power to imposer a server completely with its IP address and port still can steal player logins.
- the md5 hash sum algorithm itself is known to have some flaws; none of the flaws already found inhibit its usefulness for our purposes here, but it's only a question of time.