如何为两条腿的 OAuth 提供者存储消费者秘密?
我正在实现用于 API 身份验证的两条腿 OAuth 协议的提供者端。我们将为消费者提供消费者密钥和秘密,他们将用它们来签署请求。两条腿的 OAuth 由互操作性标准规定,因此也是一项要求。
这个秘密有点类似于密码,我通常不会将密码存储为纯文本(bCrypt 或类似的将是我的正常选择)。但由于我的提供商需要访问纯文本机密来验证签名,因此它必须采用某种纯文本或可逆形式。
我考虑了以下选项:
将秘密存储为纯文本
这是最明显的解决方案,但如果数据库以某种方式受到损害,则所有秘密都必须更改。对我来说,这个解决方案并不理想,因为它存在以纯文本形式存储密码的所有问题。
使用存储在其他地方的加密密钥应用可逆加密(例如 AES)
这将提供一定的安全性,因为如果数据库受到损害,那么秘密仍然是安全的。但可逆加密需要加密密钥,并且密钥必须存储在服务器上。这意味着如果攻击者破坏了机器,则可以绕过加密。
有什么我没想到的吗?
说明 实际上,它使用 2-leged Oauth 作为单点登录系统。 “消费者”创建一个请求,其中包括消费者密钥、随机数和几个其他参数。然后通过使用消费者密钥计算 HMAC-SHA1 来对整个请求进行签名。当请求到达我们的提供商系统时,会重复该过程,如果签名匹配,则请求处理将继续。因此,我们也需要纯文本密钥来计算我们这边的 HMAC-SHA1 签名。不幸的是,这种机制是由我们需要遵守的行业标准协议决定的。
I'm implementing the provider side of a two-legged OAuth protocol for API authentication. We will provide the consumer with a consumer key and secret, which they will use to sign requests. The 2-legged OAuth is dictated by an interoperability standard, and thus a requirement.
The secret is sort of akin to a password, and I would never normally store a password as plain text (bCrypt or similar would be my normal choice). But because my provider needs access to the plain-text secret to verify the signature, it has to be either in some plain-text or reversible form.
I've considered the following options:
Store the secret as plain text
It's the most obvious solution, but if the database is compromised somehow, then all of the secrets will have to be changed. To me this solution is not ideal because it has all of the problems of storing a password in plain-text.
Apply reversible encryption (e.g. AES) with an encryption key stored elsewhere
This will provide some security, because if the database is compromised then the secrets will still be safe. But reversible encryption requires an encryption key, and the key has to be stored on the server. It means that if an attacker compromises the machine, then the encryption can be circumvented.
Is there something I haven't thought of?
Clarification Effectively it's using 2-legged Oauth as a single-signon system. The 'consumer' creates a request including the consumer key, a nonce, and several other parameters. The whole request is then signed by computing an HMAC-SHA1 with the consumer secret. When the request reaches our provider system, the process is repeated and if the signatures match then the request processing continues. We therefore need the plain-text secret to compute the HMAC-SHA1 signature on our side too. Unfortunately this mechanism is dictated by the industry-standard protocol that we need to comply with.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您确定提供商需要纯文本密码吗?
如果是这种情况,那么您根本就无法拥有“客户秘密”。一旦客户将此秘密透露给其他人(包括您),它就不再成为秘密。
也许如果你更多地解释你想要做的事情,我们可以想出一个更优雅的方法。
Are you sure that the provider needs the plain text password?
If this is the case then you simply can't have a 'customer secret'. As soon as the customer discloses this secret to someone else (including you) it fails to become a secret any longer.
Maybe if you explained more of what you are trying to do we could come up with a more elegant appraoch.
查看上一个问题。我不是这个话题的专家,但我认为你遗漏了部分方程式。除了使用者密钥和机密之外,您还将验证发送请求的应用程序(如果您使用 RSA-SHA1,则使用 x509 证书)。
Take a look at this previous question. I'm not an expert on the topic, but I think you're missing part of the equation. In addition to the consumer key and secret, you'll be verifying the application that's sending the request (using an x509 certificate if you're using RSA-SHA1).