HTTP-based Authentication: Password Decryption
After the splash page authentication the Access Point initiates the Login process to verify whether the WiFi client was successfully authenticated by the splash page authentication server. During this process, the Access Point generates a Request Authenticator (RA), which is used to encrypt the WiFi client’s password. The encrypted password is then transmitted along with the RA.
The captive portal service is then responsible for decrypting the password using its own HTTP secret and verifying the WiFi client authentication.
Password decryption needs to be implemented by the service provider as follows:
- Convert RA and EPW from hexadecimal to binary form;
- Concatenate HTTP secret and binary RA into a single array of bytes (called ‘decryption block’) and compute its 16 bytes long MD5 checksum (called ‘key’);
- XOR the first 16 bytes of the EPW with the corresponding bytes of the key. This results in the first 16 bytes of the decrypted password;
- If the EPW is longer than 16 bytes, re-compute the decryption block by concatenating the HTTP secret with those 16 bytes of the EPW used in the previous step. Compute the MD5 of the new decryption block to obtain the new key.
- XOR the next 16 bytes of the EPW with the new key. This results in the next 16 bytes of the decrypted password. Repeat point 4 and 5 for every following group of 16 bytes of the EPW.
Please find below the pseudo code depicting the steps to be implemented.
hexRA = Hexadecimal Request Authenticator, string received via login request hexEPW = Hexadecimal encrypted password, string received via login request binRA = hexadecimal_to_binary(hexRA) binEPW = hexadecimal_to_binary(hexEPW) decrypt_block = HTTPsecret + binRA key = MD5(decrypt_block) for each block of 16 bytes [X] in binEPW do password[X] = key XOR binEPW[X] // compute the decryption block and key to be // used in the next round, if any decrypt_block = HTTPsecret + binEPW[X] key = MD5(decrypt_block) done