Problem 183 Connect Four

Back to Problem Solutions forum

gardengnome     2021-02-28 08:40:35
User avatar

Hi Rodion,

Good Morning! Could you please have a look at the page for this problem? It loads fine when not logged in but gives an error when logged in, at least for me (tested in different browsers). Might have to do with the unique keys that need to be generated.

Thank you!

Rodion (admin)     2021-02-28 14:15:15
User avatar

Mathias, Hi!

Thanks for reporting this!

That's, arrrrgh, again due to forced switch to PHP7 in the beginning of the month. Seemingly, all interactive tasks were broken, but either no one tried to solve them, or no one cared to report (perhaps, supposing this is intermittent failure).

Hopefully it is fixed now, but may be not - meaning there could be trouble when you submit success token. So it is advisable to check one of already solved problems. I tried Say-100 manually - once time it failed (perhaps, timeout) other worked.

One of the troubles is that "game" server code couldn't be updated easily now due to recent google-app-engine changes so we need the main site (with PHP7) to conform with old PHP5 code there... If tokens are found to be yet inconsistent, I'll anyway will try to figure out how to update game code.


Let details be here as I almost broke my brain while googling:

Tokens were encrypted using mcrypt_encrypt function in PHP5. It allows selection of various algorithms and flags. Particularly we were using rijndael-128 with 128 bit key and 128 bit data (i.e. both 16 bytes):

$key = hex2bin('00112233445566778899aabbccddeeff'); // 16 bytes unlike in many examples

$cipher = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $data, MCRYPT_MODE_ECB);

and on receiving side

$result = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $cipher, MCRYPT_MODE_ECB);

In PHP7 these functions are deprecated and then removed. We should use openssl_encrypt and openssl_decrypt, which also allows various algorithms and flags. Particularly it is said that rijndael means variants of aes. Regretfully no direct mapping of various modes is given.

After some kicking I found the way to encrypt identically:

$cipher = substr(openssl_encrypt($data, 'aes-128-ecb', $key, OPENSSL_RAW_DATA), 0, 16);

Here openssl_encrypt produces 32 bytes result (it appears mcrypt_rijndael_128 meant 128 data block sizes, but for aes-128-ecb it is about 128 bit key size) - hence result is truncated at the middle.

As about decryption, it won't work straightforward with halved result. However on the brink of despair it was found that additional flag is needed:

$result = openssl_decrypt($cipher, 'aes-128-ecb', $key, OPENSSL_RAW_DATA|OPENSSL_ZERO_PADDING);

hopefully someone won't try hacking our 128 bit key after these explanations - though it seems to be feasible by modern standards, it is far less time-consuming to solve the task itself :)

gardengnome     2021-02-28 14:53:09
User avatar

Many thanks for the speedy response and resolution. I just tried Say 100, Maze of the Wumpus and the very first exchange for Connect Four - all work, so I think we are good.

Please login and solve 5 problems to be able to post at forum