我正在考虑为IMAP和SMTP服务器实施CRAM-MD5身份验证。问题是CRAM似乎需要一个明文密码才能随时可用。服务器向客户端发送唯一的质询,客户端返回:
MD5( MD5(password, challenge), MD5( password ) )
如果没有明确的文本密码,我看不到检查方法,规范没有说明 有一个可用,但它似乎是合乎逻辑的。
我能想到的唯一解决方案是将密码加密(正确加密,而不是哈希)到数据库中(可能使用基于RSA密钥的AES,因为我已经有了处理它的东西)并在需要时解密它比较,似乎是一个非常缓慢的方式,因为它需要解密和散列SMTP和IMAP上的每一次登录。
这是最佳解决方案/最有效的解决方案吗?
或者更好的是,CRAM现在已经过时了,因为现在使用SSL可以保证线路上的安全认证不那么安全吗?
答案 0 :(得分:1)
目前有一份RFC草案建议将DIGEST-MD5移至历史状态,CRAM MD5也处于更好的状态。
如果您需要适当的安全性,请从TLS和SASL开始 - 在该模式下,PLAIN被认为是可接受的,但是,如果您担心它不满意,那么我建议在它之上实现GSSAPI或NTLM
答案 1 :(得分:1)
诀窍是你真正需要的是密码的未定义md5,它与md5上下文的中间状态相同。
MD5_CTX ctx;
MD5Init(&ctx);
MD5Update(&ctx, password, length);
如果您这样做,然后将ctx
的值存储为hashed
,那么可以在CRAM MD5中使用它的副本,就像这样
代表MD5(password, challenge)
MD5Update(&hashed, challenge, length);
MD5Final(&digest, &hashed);
和MD5( password )
MD5Final(&digest, &hashed);
MD5( MD5(password, challenge), MD5( password ) )
的其余部分相当简单
我本来希望在这个例子中使用python但是在标准md5中没有办法访问md5对象的状态所以我使用了libmd5的api
答案 2 :(得分:1)
hashlib.py的Python源代码表示您可以使用二进制数据初始化哈希实例,但从使用情况来看,它似乎意味着“使用此数据的哈希初始化”。
但是,您可以使用内部状态完整地克隆对象,因此您可以挑选对象并存储该对象以代替密码。要获取密码MD5,取消对象的攻击,并获取挑战哈希值,请将其取消,并使用质询数据调用它的update()方法。