Mysql and php, password protection

An often used combination for a website is php with mysql as database backend. This implies that the web server must be able to connect to the database. For this it needs a mysql account and password. A typical (but unsafe) solution is to store the account name and password somewhere in a file in the document tree of the website which is then read by a php script that makes the mysql connection. This is not safe because this file has to be readable for the webserver. On a webserver which hosts multiple sites it implies that the file must be readable for the user www, in practice this often means readable for the world. This means that the file is readable for everyone who has an Science account. Apart from that there is the risk that the file can be read through the webserver.

There is a solution for this problem, instead of including the password in plain text in a file, one can encrypt the password with a website specific secret key. In the php code which makes the connection with the mysql server you replace the line which sets the password:
$admin-password = "plaintextpassword";
by
## EXTRA construction to protect the password
require_once( "passwd-crypt.inc.php" );
$admin_password = decrypt("ENCRYPTED PASSWORD");
where “ENCRYPTED PASSWORD” has to be replaced with the string you receive from C&CZ. Beware that in case this assignment is done in a class, this has to be placed in the constructor of the class. Copy the text below into a file passwd-crypt.inc.php

<?php

function hex2bin($hexdata) {
$bindata = '';
for ($i=0;$i<strlen($hexdata);$i+=2) {
$bindata.=chr(hexdec(substr($hexdata,$i,2)));
}
return $bindata;
}

function decrypt($crypted_admin_password) {
// secret krijg je van Apache uit website specifiek vhost file
$secretkey = $_SERVER["SECRET"];

$td = mcrypt_module_open('rijndael-256', '', 'ecb', '');

mcrypt_generic_init($td, $secretkey, NULL);
$admin_password = rtrim( mdecrypt_generic($td, hex2bin($crypted_admin_password)), '\0');
mcrypt_generic_deinit($td);
mcrypt_module_close($td);

return $admin_password;
}

?>

If you want to use this construction send a mail to Postmaster [mailto:postmaster@science.ru.nl?subject=SecureMysql&body=Database:%0DWebsite:] with the name of the database and website.