没有明文密码的Exchange Web服务器到服务器身份验证?

Ric*_*an7 5 outlook exchange-server calendar exchangewebservices office365

我正在构建一个运行自动化流程的服务器应用程序,该流程需要与Exchange服务器兼容,直到2007版本.我目前通过Azure AD使用OAuth进行Office 365连接,但我仍在尝试为内部部署找到解决方案2013年之前的交流.

我一直在阅读有关Exchange身份验证(基本,NTLM等)的内容,我似乎无法找到任何对长期令牌系统的引用,这将允许我使用一次性密码设置身份验证.我非常强烈不愿意将用户密码存储在中央数据库中,加密与否,因为它具有巨大的安全责任,可以进行逆向工程.

有什么我想念的吗?

有没有办法在没有密码的情况下每次对Exchange进行身份验证?

Ric*_*an7 4

作为后续回答我自己的问题,因为我对某些答复和/或通过广泛搜索找到的内容不满意。

经过对 Exchange 服务器、它们的身份验证方式以及支持和使用的协议进行大量研究后,我发现了我认为最好的选择:NTLM

现在,让我解释一下。

我试图实现的目标如下:

  • 能够对 Exchange 2007+ 服务器进行身份验证
  • 通过初始过程使身份验证成为“一次性设置”
  • 切勿存储纯文本密码(尤其是在平台/服务中央数据存储中)

考虑到这些要点:

  • 我无法使用“基本”身份验证,因为它需要将用户密码以纯文本形式存储在中央数据存储中
  • OAuth 不起作用,因为它仅在 Exchange 2013+ 上受支持

这样一来,我就只剩下 NTLM 了。不幸的是,我知道 NTLM 有着悠久的历史,在其多年的遗产中存在安全缺陷,但我更深入地研究它,看看它是否能够以某种方式满足我的要求。

不幸的是,NTLM 的规范长期以来一直处于“秘密”状态。这是一个专有规范,因此不幸的是,有关其内部结构的信息相当罕见。很长一段时间以来,有关 NTLM 的规范信息的唯一真正来源实际上是逆向工程的信息(感谢 Eric Glass!)不过值得庆幸的是,微软最近终于开始在其 MSDN 站点上发布有关 NTLM 的文档。

在深入研究该协议并在测试 Exchange 服务器上以许多不同的配置排列运行一些测试后,我意识到 NTLM 实际上可以满足我的所有要求。如何?好吧,由于协议的工作方式,一旦凭证被散列(以规范 [LM、NTv1、NTv2] 中可能的 3 种方式之一),就不需要再次对相同的凭证进行散列目标。这意味着,类似于对典型注册机制的用户密码进行哈希处理,您可以简单地预先请求 Exchange/NTLM 凭据,然后对凭据进行一次哈希处理。


笔记!!!有一个问题!

Keep in mind that being able to hash the credential once and use it multiple times means that the hash is somewhat of a "password equivalent". What I mean by that, is that the hash can be used like a password once it's known, since it's one of the only pieces of information needed to authenticate in the future. (This is known colloquially as "pass-the-hash").

Considering the alternative, however, of storing a password in plain-text, this is still much better. Why? Because at least you're not storing a raw credential that could be used in any other authentication scheme or leaking a password that may be shared in other environments (yes, people unfortunately do actually do that).

Given that knowledge, great care should still be taken when storing these hashed credentials. Finally, if another stronger authentication scheme is able to be used, use it.


So, thanks to the way that the NTLM protocol works, it meets the requirements:

  • Be able to authenticate to an Exchange 2007+ server
    • NTLM is available in all Exchange servers 2007+
  • Have the authentication be a "one-time-setup" through an initial process
    • The credentials and target need only be entered once, as once an initial handshake is made with the server you'll know that the auth scheme works. (This of course doesn't consider that a remote Exchange server's configuration could be changed at any time. So proper error handling should still very much be put in place)
  • Never store plain-text passwords (particularly in a platform/service central datastore)
    • The hashed credential is stored instead. However great care should be taken, with a potentially dual-encryption technique employed, due to the "catch" explained in the earlier note.

Anyway, I hope someone else finds this at some point so that they don't have to do quite as much specification reading and experimentation as I had to.

Also, for what it's worth, as I noticed that open-source implementations of NTLM are not only rare but also more commonly only half-complete, my team has open-sourced our NTLM implementation in PHP. It's available on GitHub.