CRAM-MD5 实施

发布于 2024-11-25 08:40:33 字数 455 浏览 2 评论 0原文

我正在考虑为 IMAP 和 SMTP 服务器实施 CRAM-MD5 身份验证。问题是 CRAM 似乎需要始终提供明文密码。服务器向客户端发送一个独特的质询,然后客户端返回:

MD5( MD5(password, challenge), MD5( password ) )

如果没有明文密码,我看不到一种方法来检查这一点,规范没有说必须有一个可用的密码,但是这似乎合乎逻辑。

我能想到的唯一解决方案是将密码加密(正确加密,而不是散列)到数据库中(可能使用基于 RSA 密钥的 AES,因为我已经有一些东西要处理)并在需要比较时解密,不过,这似乎是一种非常缓慢的方法,因为 SMTP 和 IMAP 上的每次登录都需要解密和散列。

这是最好的解决方案/最有效的解决方案吗?

或者,更好的是,CRAM 现在已经过时了吗?因为现在通过 SSL 来保护安全性较低的线路身份验证?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

苍白女子 2024-12-02 08:40:33

诀窍在于,您真正需要的是未最终确定的密码 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(密码)

MD5Final(&digest, &hashed);

其余的 MD5(MD5(密码,质询),MD5(密码)) 相当简单,

我希望本示例使用 python,但在标准 md5 无法访问 md5 对象的状态,所以我使用了 libmd5 的 api

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

轻许诺言 2024-12-02 08:40:33

目前有一个 RFC 草案提议将 DIGEST-MD5 移至历史状态,CRAM MD5 也没有处于更好的状态。

如果您想要适当的安全性,请从 TLS 和 SASL 开始 - 在这种模式下,PLAIN 被认为是可以接受的,但是,如果您认为它不令人满意,那么我建议在其之上实现 GSSAPI 或 NTLM。

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.

萌︼了一个春 2024-12-02 08:40:33

hashlib.py 说您可以使用二进制数据初始化哈希实例,但从用法来看,它似乎意味着“使用该数据的哈希值初始化”。

但是,您可以在其内部状态完好无损的情况下克隆该对象,因此您可以腌制该对象并存储它来代替密码。要获取密码 MD5,请解封该对象;要获取质询哈希值,请解封它并使用质询数据调用它的 update() 方法。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文