开发者

CRAM-MD5 Implementation

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 soluti开发者_如何学Con?

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.

MD5_CTX ctx;
MD5Init(&ctx);
MD5Update(&ctx, password, length);

if you do this and then store the value of ctx as hashed, then one can then use copies of it in CRAM MD5 like this

for MD5(password, challenge)

MD5Update(&hashed, challenge, length);
MD5Final(&digest, &hashed);

and for MD5( password )

MD5Final(&digest, &hashed);

the rest of MD5( MD5(password, challenge), MD5( password ) ) is rather simple

i 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


There is currently a draft RFC proposing to move DIGEST-MD5 to historical status, CRAM MD5 isn't in a much better state either.

If you want proper security, start with TLS and SASL - in that mode, PLAIN is considered acceptable, but, if as far as you're concerned it's not satisfactory, then I would recommend implementing GSSAPI or NTLM on top of it.


The sources for Python of hashlib.py say that you can initialize a hash instance with binary data but from the usage it seems to mean "initialize with the hash of this data".

However, you can clone the object with it's internal state intact, so you could pickle the object and store that in lieu of the password. To get the password MD5, unpickle the object, and to get the challenge hash, unpickle it and call it's update() method with the challenge data.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜