Dovecot Password Creation from PHP

I’m currently working on making a Laravel based management system for my new mail service that I have setup using the Christoph Haas’ ISPmail Tutorial, Ars Technica’ Email Server Tutorial and others. I needed to be able to create Dovecot compatible passwords from my PHP application.

So when it came to the day-to-day management of the system I didn’t want to run SQL commands to manage the user accounts, so I started building a web based management console. When it came to creating the user’s password I ran into a small problem, I couldn’t use the doveadm pw command because the dovecot software is installed on the mail server and while the management console will be installed on my web server – two different machines. I didn’t want to install Dovecot on my web server – for reasons, so I had to find a different way of creating the user’s password. So I looked at my options to create the password in PHP, after after many hours of researching it. I found the solution – which when I found it made me feel like an idiot.

So to help anyone else that may be looking for a way to create dovecot passwords using a more secure password than MD5, via PHP. Below are the different methods of creating a Dovecot supported password in PHP.

Dovecot PHP Snippets

SHA512-CRYPT

$password = "PlainTextPassword";
$salt = substr(sha1(rand()), 0, 16);
$hashedPassword = "{SHA512-CRYPT}" . crypt($password, "$6$$salt");

SHA512 Base64 Encoded

$password = "PlainTextPassword";
$salt = substr(sha1(rand()), 0, 16);
$hashedPassword = "{SHA512.b64}" . base64_encode(hash('sha512', $password, true));

SHA256-CRYPT*

$password = "PlainTextPassword";
$salt = substr(sha1(rand()), 0, 16);
$hashedPassword = "{SHA256-CRYPT}" . crypt($password, "$5$$salt");

SHA256 Base64 Encoded*

$password = "PlainTextPassword";
$salt = substr(sha1(rand()), 0, 16);
$hashedPassword = "{SHA256.b64}" . base64_encode(hash('sha256', $password, true));

SSHA512-CRYPT (Salted)

$password = "PlainTextPassword";
$salt = substr(sha1(rand()), 0, 16);
$hashedPassword = "{SSHA512}" . base64_encode(hash('sha512', $password . $salt, true) . $salt);

SSHA256-CRYPT (Salted)

$password = "PlainTextPassword";
$salt = substr(sha1(rand()), 0, 16);
$hashedPassword = "{SSHA256}" . base64_encode(hash('sha256', $password . $salt, true) . $salt);

* Denote code that should work, but has not been directly tested. All testing involved PHP 7.

Be sure to change the salting to something either with more entropy or another function of your desire.

Be sure to test the outputted hash against your install of Dovecot by running the following command.

doveadm pw -t 'HASHED Password From Function' -p $password 

So, to test the outputted hash for the password “password123”, and assuming the function output was:

{SHA512-CRYPT}$6$24fd51974df4aa22$JiLGcBXH7JLQcRbcAyFV52r4OOVv4PbmX88E7IB22T/lJsg3/oTI.rAGcWizqV8iyYgDQ4fE9oezojT/hBfdF/ 

You would run the following command in your terminal:

doveadm pw -t '{SHA512-CRYPT}$6$24fd51974df4aa22$JiLGcBXH7JLQcRbcAyFV52r4OOVv4PbmX88E7IB22T/lJsg3/oTI.rAGcWizqV8iyYgDQ4fE9oezojT/hBfdF/' -p password123 

Aside: I would use the blowfish encryption scheme, but my server does not support it, so I used the next best thing. Also, I know there are many virtual mail management systems out there (ViMbAdmin), but I’m planning to built certain functionality of this management portal into other services I will offer to clients. I will also open source my management console, after I have clean up the code.