我一直在研究保护 API 在 Android/iPhone 应用程序或网站应用程序中使用的技术。
我找到了一种我喜欢的技术,但不确定它是否好或者有什么问题(除了是一个相当长的过程之外)。
处理(最初是用户方):
首先,通过对用户密码进行哈希处理来创建盐。
然后通过散列请求的 url(通过查询字符串在末尾附加用户名)和盐来创建签名。
最后通过对用户名和签名进行哈希处理来创建 token 。
token 在 header 内传递到服务器(每次)。
第一个请求:
第一个请求必须针对验证端点,并包含 device_id 作为查询字符串。
在服务器上进行相同的处理(如上所述),如果 token 与用户发送的 token 匹配,则 device_id 将存储在数据库中并分配给该用户名以供将来引用(设备 ID 可在请求的 url 中找到)并用于此后验证用户名/设备。
所有后续请求:
现在每个请求的处理必须在用户端和服务器端进行,并且每次的 token 都不同(随着请求的 URL 的变化)。
由于尚未编写,因此不包含任何代码。
最佳答案
您的身份验证模型是共享 secret 身份验证。在您的情况下,您的用户密码充当共享 secret 。您需要确保有一种安全的方式提前获取用户和服务器的密码。为了签署请求,您需要创建一条包含所有请求 header 和数据的消息。然后对该请求进行哈希处理。然后该哈希( token )将随请求一起传递。服务器将在服务器上执行相同的签名和哈希过程并确保 token 匹配。
在您的示例中,您听起来像是想使用以下伪代码创建 token :
Token = hmac-sha1( Hash(Pasword + Salt) + RequestUrl + UserName )
你的方法还不错,但我会将你的方法与亚马逊的 REST Auth 模型进行比较,并实现他们详细说明的更接近的版本。 http://s3.amazonaws.com/doc/s3-developer-guide/RESTAuthentication.html
他们的实现:
"Authorization: AWS " + AWSAccessKeyId + ":" + base64(hmac-sha1(VERB + "\n"
+ CONTENT-MD5 + "\n"
+ CONTENT-TYPE + "\n"
+ DATE + "\n"
+ CanonicalizedAmzHeaders + "\n"
+ CanonicalizedResource))
他们有充分的理由包含您遗漏的一些字段,包括但不限于:
- 时间戳是为了防止重放攻击。
- 内容-MD5是为了防止人们篡改请求数据(与 发布和放置)
关于api - 基于 REST 的 API 的安全性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14337177/