简体   繁体   English

HMAC在PHP中进行Web服务认证的实现

[英]HMAC Implementation for Web Service Authentication in PHP

I am trying to implement a web service and need some (very) simple Authenticate to restrict access to the service. 我正在尝试实现Web服务,并且需要一些(非常)简单的Authenticate来限制对该服务的访问。

I found out about HMAC and I think I understand how to implement it. 我发现了有关HMAC的知识,我想我知道如何实现它。 But I have a couple of questions in mind. 但是我有几个问题在想。

Let's say I have this HTML Form on the consumer side. 假设我在消费者方面拥有此HTML表单。 When making a GET/POST request to my server. 向我的服务器发出GET / POST请求时。

  1. Is is enough to create a hash of: public_key using the secret_key ? 是足以创造的哈希: public_key使用secret_key
  2. OR, do I need to create a hash of the entire POST variables/array? 或者,是否需要创建整个POST变量/数组的哈希?

I'm thinking it would be enough to send the hash of the public_key only but just wanted to make sure and ask you guys. 我认为仅发送public_key的哈希值就足够了,但是只是想确定并询问你们。

I am planning to do this: 我打算这样做:

  1. Create a hash of the public_key 创建public_key的哈希
  2. Put the hash in a hidden field or in the URL as a param together with the public_key (or client_id) and other POST/GET variables. 将哈希值与public_key(或client_id)以及其他POST / GET变量一起放在隐藏字段或URL中作为参数。
  3. Receive on my server and verify the hash against the database by recreating the hash of the public_key using the secret_key . 在我的服务器上接收并通过使用secret_key重新创建public_key的哈希来验证数据库的哈希。
  4. If the hash matches, I accept the POST/GET requests. 如果哈希匹配,则我接受POST / GET请求。

Your thoughts? 你的意见?

Clarification: public_key is like the client unique id where I can use to identify what secret key to use to generate the hash on the server. 澄清: public_key就像client unique id ,我可以在其中使用它标识用于在服务器上生成哈希的secret key

The pubkey is just used as an alternative way to recognize the user. pubkey仅用作识别用户的替代方法。 It could be the user email as well, by the way since you don't likely want to expose your user data to their programmer (or to potential sniffers) you create a unique identifier for each user. 顺便说一句,它也可能是用户电子邮件,因为您不希望将用户数据公开给他们的程序员(或潜在的嗅探者),所以您要为每个用户创建一个唯一的标识符。 It's all it means. 这就是全部。 Then you need a private key to sign your hash. 然后,您需要一个私钥来对您的哈希签名。

Of course to make it worth it you have to sign all unique request data, otherwise someone could alter your request body and you wouldn't be able to detect it (MITM attack). 当然,要使其物有所值,您必须对所有唯一的请求数据进行签名,否则有人可以更改您的请求正文,而您将无法检测到它(MITM攻击)。

You also should care of creating a timestamp that must be included in the HMAC itself, then pass it alongside with the request. 您还应该注意创建必须包含在HMAC本身中的时间戳,然后将其与请求一起传递。 This way you can make the signature expirable and so you are not exposed to replay attacks (someone steals the request and without modifying it replies it against the server, operating multiple times the same action... think what a problem if it's a request to pay for your service, your user would be very very angry with you). 这样,您就可以使签名失效,这样您就不会受到重放攻击(有人窃取了该请求,并且未经修改就对服务器进行了回复,多次执行相同的操作……如果这是对服务器的请求,请考虑有什么问题)为您的服务付费,您的用户会对您非常生气)。

Also remember (nobody does) to encrypt also the Request-URI inside the HMAC itself and also the HTTP method (aka verb) if you're using a RESTful webservice, otherwise malicious users will be able to send the request to other URIs or (using RESTful services) change the meaning of your request, so a valid GET can become a potential DELETE. 另外请记住(如果没有),也要加密HMAC本身内的Request-URI和HTTP方法(也称为动词)(如果您使用的是RESTful网络服务),否则恶意用户将能够将请求发送到其他URI或(使用RESTful服务)更改请求的含义,因此有效的GET可能会成为潜在的DELETE。 An example could be: user wants to see all its data, makes a GET request, a Man in the Middle reads the request and changes GET with DELETE. 一个例子可能是:用户希望查看其所有数据,发出GET请求,中间人读取请求并使用DELETE更改GET。 You are not given the opportunity to detect that something has been changed if it's not inside your HMAC you can check about, so you receive a DELETE request and boom! 如果您不在可以检查的HMAC内,则没有机会检测到某些内容已更改,因此您将收到DELETE请求,并且工作异常 you destroy all user data. 您销毁所有用户数据。

So always remember: everything is essential to your request must be validable And if you rely on a HMAC then you must encrypt everything you need to trust the request. 因此请始终记住: 对您的请求至关重要的所有内容都必须是有效的,并且如果您依赖HMAC,则必须对信任请求所需要的所有内容进行加密。

Also always remember to start designing your system by denying all request, then if you can validate them perform requested actions. 还请始终记住要通过拒绝所有请求来开始设计系统,然后如果您可以验证它们是否执行请求的操作。 This way you always fall back on denied requests. 这样,您始终会回退拒绝的请求。 It's better to have a user email telling you that he cannot do something that have your user data propagated on the net. 最好有一封用户电子邮件告诉您,他不能做某些事情,使您的用户数据在网络上传播。

Use TLS. 使用TLS。 It fixes this and a host of problems you haven't even thought of yet. 它可以解决此问题以及您甚至尚未想到的许多问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM