PBKDF2 password hashing as in ASP.NET Core

Aki Tuomi aki.tuomi at open-xchange.com
Sun Aug 30 17:33:04 EEST 2020

> On 29/08/2020 23:49 Yves Goergen <nospam.list at unclassified.de> wrote:
> Hello,
> I'm setting up a new server and, again, seek for a decently secure (from 
> a security specialist's POV) way to store and verify user passwords in a 
> database. Additionally now, GDPR requires me to use a solid 
> state-of-the-art solution.
> My OS is Ubuntu 20.04, Dovecot version 2.3.7, database backend with 
> PostgreSQL 12.
> Obviously, storing the plaintext password is a terrible idea. SHA-based 
> methods aren't suitable either. bcrypt has been recommended often [1]. 
> PBKDF2 was preferred over bcrypt even more [2]. I'm managing all 
> database contents with an ASP.NET Core application that implements the 
> management user frontend. It's a bit hard to find bcrypt support for 
> .NET (there are a few NuGet packages of unknown quality [3]).
> .NET does however implement, use and recommend PBKDF2 for its own user 
> management. If this is by far the best way to go, I'm already covered on 
> that side. Now the problem is, once again*, how I can use this in 
> applications to make them as secure.
> I need a solution for Dovecot and Exim. Exim seems to be able to ask 
> Dovecot (IMAP) for user authentication, so I might try that and only 
> need to solve the problem in Dovecot alone.
> Dovecot documentation says that PBKDF2 is somewhat possible [4]. It 
> requires the hash in the format "$1$salt$rounds$hash". I guess that 
> "salt", "rounds" and "hash" are the parameters here. But what is their 
> format?
> The .NET implementation [5] describes its format as "{ 0x01, prf 
> (UInt32), iter count (UInt32), salt length (UInt32), salt, subkey }" 
> with big-edian integers. The result is base64-encoded. Prf is an enum 
> value, describing the HMAC SHA-256. Subkey is the hash value part.
> I might find a way to convert .NET's format into what Dovecot 
> understands. The hmac is SHA-256, the rounds is 10000. But I wasn't able 
> to get it working.
> My test password is: simplepassword
> The .NET hash: 
> The converted hash for Dovecot: 
> $1$bQCfNv28o6qwArEvKFd50A==$10000$kyaB6z9/NYSoigR7jx4THZI6lvAZLPERTkGS7LCdoK0=
> I've also found the source code in Dovecot that should verify the hash 
> [6]. It gives some more hints about the expected format that are sadly 
> missing from the documentation, making it almost useless. I also tried 
> with the "{PBKDF2}" prefix, with the base64 padding "=" removed and with 
> the hash part converted from base64 to hex. Nothing works. The source 
> mentions "SHA1" somewhere. Is that all it can accept? No up-to-date SHA-256?
> So what have I done wrong here? Why can't I authenticate? The Dovecot 
> log isn't helpful, it doesn't even mention the user name I tried to log 
> in with from Thunderbird, most of the time (it's unpredictable).
> What is the correct usage of Dovecot's PBKDF2 feature? Is it functional 
> at all? There's a test case for it [7] but that's not helpful to me.
> If Dovecot's PBKDF2 support is not functional or not compatible with 
> ASP.NET Core's parameters, what options do I have? Can I build my own 
> authentication service that Dovecot can communicate with, to fill the 
> gap of missing crypto support?
> Yves


The PBKDF2 algorithm is standard and should be compatible with ASP.NET Core.

The salt parameter is 16 symbols from the salt character set


followed by number of rounds

hash is hex encoded 160-bit value which comes out of the PBKDF2 function with SHA1.

Dovecot does not currently have support for PBKDF2-SHA256, only PBKDF2-SHA1. You could use CRYPT-SHA512 instead which is probably just as good?


More information about the dovecot mailing list