应用程序到应用程序身份验证/访问控制(无需 HTTPS)
在我目前正在进行的项目中,我们遇到以下问题。
我们的软件是一个基于位置的服务平台,应用程序可以使用 SOAP 通过我们公开的 Web 服务连接和使用我们的服务。到目前为止,我们的平台仅由内部应用程序使用,但现在我们希望将其开放给第三方应用程序。为此,我们需要一个身份验证机制。
由于我们客户的基础设施和负载平衡解决方案的原因,我们无法使用 HTTPS。最初的想法是应用程序可以只使用 HTTPS 并发送我们验证的密码。
下一个解决方案是: 该应用程序有密码。应用程序生成一个随机字符串(盐)并创建一个哈希值。然后应用程序创建一个 HTTP 请求,发送哈希、盐和时间戳。这三个足以让我们进行身份验证,因为我们可以生成相同的哈希值并进行比较。
我的问题是,为此我们需要以明文形式将密码存储在数据库中,因为我们需要使用给定的盐执行相同的过程,以便我们可以比较结果并验证应用程序。以明文形式存储密码是不可接受的。
您知道适合这种情况的身份验证/访问控制机制吗?一般来说,您知道有关应用程序身份验证/访问控制机制的任何好书/资料吗?
非常感谢任何帮助。提前致谢!
On the current project I'm working on, we have the following problem.
Our software is a Location Based Services platform and applications can connect and use our services through our exposed webservices using SOAP. Until now our platform was only used by internal applications, but now we would like to open it for third party applications. For that we need an authentication mechanism.
Because of our customers' infrastructure and load balancing solution, we cannot use HTTPS. The original idea was that applications can just use HTTPS and send the password we authenticate.
A solution would be the next:
The application has the password. The application generates a random string (salt) and creates a hash. Then the application creates an HTTP request sending the hash, the salt and a timestamp. This three is enough for us to authenticate, as we can generate the same hash and compare.
My problem is that for this we need to store the password in our database in clear text, because we need to do the same process using the given salt so we can compare the result and authenticate the application. Storing passwords in clear text is unacceptable.
Do you know about any authentication/access control mechanism that would fit this situation? Generally, do you know about any good books/sources about application authentication/access control mechanisms?
Any help is highly appreciated. Thanks in advance!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
应用程序(客户端)可以对密码进行两次哈希处理。请注意,服务器应该生成其他随机盐,而不是客户端!否则,攻击者也可以使用此哈希进行登录。您还可以通过在数据库中存储密码特定的盐来使其更安全。
协议:
0) 服务器从数据库中检索特定密码的
salt
,生成 salt2,并将两者发送到客户端1) 客户端发送
hash(hash(password, salt), salt2, timestamp )
和时间戳
。2) 服务器从数据库中检索
hash(password, salt)
并进行比较。请注意,如果您所在的网络中攻击者不仅可以嗅探,还可以修改流量,如 Paulo 指出,您应该签署每条消息:
hash(hash(password, salt), salt2, timestamp, message)
并在服务器上检查它。 (例如,攻击者可以修改消息以包含删除命令的情况...)请注意,当用户需要安全地设置/更改密码时仍然存在问题。您无法仅使用不安全网络上的哈希函数来安全地完成此操作,您需要某种密码/解密。
另请注意,哈希函数越慢,就越安全(因为字典攻击)。如果您无法访问特殊的慢速哈希函数,您也可以调用普通的快速哈希函数 100000 次。
The application (client) can hash the password two times. Note that the server should generate the other random salt, not the client! Otherwise the attacker can log with this hash also. You can also make it safer by storing password specific salt in the database.
The protocol:
0) servers retrieves
salt
for that particular password from database, generates salt2, and sends both to the client1) client sends
hash(hash(password, salt), salt2, timestamp)
andtimestamp
.2) server retrieves
hash(password, salt)
from the database and compares.Note that if you are on the network where attackers can not only sniff, but also modify the traffic, as Paulo pointed out, you should sign EVERY message:
hash(hash(password, salt), salt2, timestamp, message)
and check it at server. (E.g. for the case when the attacker could modify the message to contain delete command...)Note that there is still a problem when user needs to SET/CHANGE the password safely. You cannot do it safely with just hash function over unsafe network, you need some kind of cipher/decipher.
Also note that the slower the hash function is, the safer (because of the dictionary attack). If you don't have access to special slow hash function, you may also call normal fast hash function 100000 times.
您不应该发明自己的解决方案,而应该使用已建立的解决方案。 SOAP 支持加密身份验证,例如 WS-Security - 请参阅 Craig Forster 对此答案的评论以获取建议。
其他情况下的最佳选择通常是 oauth;它提供授权和身份验证,并处理许多您在构建自己的系统时不太可能发现的加密问题。
Instead of inventing your own solution, you should use an established one. SOAP has support for cryptographic authentication such as WS-Security - see Craig Forster's comment on this answer for suggestions.
The best choice in other cases is usually oauth; it provides both authorization and authentication, and deals with a lot of cryptographic issues that you're not likely to spot when building your own.
使用不包含整个消息(或流)完整性检查的身份验证解决方案是不安全的。
而哈希解决方案最初由 Thomas T. 提出(
hash(hash(password, salt), salt2, timestamp)
,其中hash(password, salt)
存储在数据库,并且salt2
是新生成的)确保攻击者无法获取密码(或时间戳过期后对登录有用的任何数据),它本身并不能阻止主动攻击攻击者在之后劫持会话身份验证,并发送任何想要的 SOAP 请求(并拦截响应)。这里需要某种方法来确保没有数据被更改。这称为消息验证码 (MAC)。 MAC 的通常定义包括一些(共享秘密)密钥和作为输入的消息,以及作为输出的身份验证令牌。
使用此功能的通常方法是在通信开始时进行一些经过身份验证的密钥交换(使用共享秘密或某些已知的公钥),然后使用现在共享秘密的一部分作为 MAC 密钥,即然后用于验证以下消息。
(这样做本质上是对 SSL/TLS(或其部分)的重新发明,可能会再次犯同样的错误。)
如果您只有一条消息要发送,您可以使用 MAC 作为一种对称签名,使用密码哈希(用慢速哈希函数加盐并生成)作为 MAC 密钥。
查看此问题的另一种方法是将要验证的消息作为 Thomas T 身份验证方案中外部哈希的输入。 (确保验证所有值得验证的内容。)
Using an authentication solution which does not contain an integrity check of the whole message (or stream) is insecure.
While the hashing solution originally proposed by Thomas T. (
hash(hash(password, salt), salt2, timestamp)
, wherehash(password, salt)
is stored in the database, andsalt2
is newly generated) makes sure than an attacker can't get the password (or any data which will be useful for logging in after the timestamp expires), it alone does not prevent an active attacker to hijack the session after the authentication, and send any SOAP requests wanted (and intercept the responses).What would be needed here is some way to make sure that no data is changed. This is known as a message authentication code (MAC). The usual definition of a MAC includes some (shared secret) key and the message as input, and an authentication token as output.
The usual way to use this would be to do some authenticated key exchange at the beginning of the communication (using either a shared secret or some known public key), and then use a part of the now shared secret as the MAC key, which is then used to authenticate following messages.
(Doing this then essentially is a reinvention of SSL/TLS (or parts thereof), potentially doing the same mistakes again.)
If you have only one message to send, you can instead use the MAC as a kind of symmetric signature, using the password hash (salted and generated with a slow hash function) as a MAC key.
Another way to view this would be to take the message to authenticate as an input to the outer hash in Thomas T's authentication scheme. (Make sure to authenticate everything that is worth authenticating.)