PHP Decoding MySQL's .mylogin.cnf
<?php // tested with PHP 7.1.7 | |
$start = microtime(true); | |
const LOGIN_KEY_LEN = 20; | |
const MY_LOGIN_HEADER_LEN = 24; | |
const MAX_CIPHER_STORE_LEN = 4; | |
$raw = file_get_contents(__DIR__ . '/mylogin.cnf'); | |
$fp = 4; // skip null bytes | |
$b = substr($raw, $fp, LOGIN_KEY_LEN); | |
$fp = MY_LOGIN_HEADER_LEN; | |
// extract key | |
$key = array_pad([], 16, 0); | |
for ($i = 0; $i < LOGIN_KEY_LEN; $i++) { | |
$key[$i % 16] ^= ord($b[$i]); | |
} | |
$key = pack('C*', $key[0], $key[1], $key[2], $key[3], | |
$key[4], $key[5], $key[6], $key[7], | |
$key[8], $key[9], $key[10], $key[11], | |
$key[12], $key[13], $key[14], $key[15]); | |
$settings = []; | |
while ($fp < strlen($raw)) { | |
$b = substr($raw, $fp, MAX_CIPHER_STORE_LEN); | |
$fp += MAX_CIPHER_STORE_LEN; | |
$cipher_len = unpack('V', $b); | |
$b = substr($raw, $fp, $cipher_len[1]); | |
$fp += $cipher_len[1]; | |
$plain = trim(openssl_decrypt($b, 'aes-128-ecb', $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING)); | |
if (preg_match('/^(\w+) = (.*)/', $plain, $matches)) { | |
$settings[$matches[1]] = $matches[2]; | |
} | |
} | |
// in my VM, this took about 1/10th of a millisecond, float(0.00011301040649414) | |
$end = microtime(true); | |
var_dump($end - $start); | |
var_dump($settings); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This comment has been minimized.
robocoder commentedNov 13, 2017
Generate the .cnf file using
mysql_config_editor
and copy to the current folder.