I’m looking at implementing CRAM-MD5 authentication for an IMAP and SMTP server. Problem is that CRAM seems to require a clear text password to be available at all times. The server sends the client a unique challenge and the client returns:
MD5( MD5(password, challenge), MD5( password ) )
I can’t see a way to check this without having a clear text password, the specification doesn’t say it has to have one available but it only seems logical.
The only solution I can come up with is to encrypt (properly encrypt, not hash) the password into the database (probably using RSA key based AES, as I already have something to deal with that) and decrypt it when I need to compare, seems a very slow way around though as it will need decrypting and hashing for every single login on SMTP and IMAP.
Is this the best solution / most efficient solution?
Or, better, is CRAM out-of-date now because even less secure authentication over the wire is secured with SSL now?
the trick is that all you really need is the unfinalized md5 of the password which is the same as the intermediate state of the md5 context before finalizing.
if you do this and then store the value of
ctxashashed, then one can then use copies of it in CRAM MD5 like thisfor
MD5(password, challenge)and for
MD5( password )the rest of
MD5( MD5(password, challenge), MD5( password ) )is rather simplei would have liked to use python for this example but in the standard md5 there is no way to get access to the state of a md5 object so i used libmd5’s api