Rest API身份验证方法-我做得正确吗?

Rest API身份验证方法-我做得正确吗?,rest,authentication,authorization,private-key,public-key,Rest,Authentication,Authorization,Private Key,Public Key,我对构建API身份验证非常陌生,所以我想确保我的做法是正确的,因为可能存在我不知道的重大安全缺陷 它基于一个秘密/私钥对,客户机和服务器都知道这个秘密密钥,但显然它从来没有被传递过 对于此方法中的任何反馈、见解或漏洞,我们将不胜感激 第1步: 客户机希望向API发出请求,因此请求服务器提供一个nonce,传递他们的公钥 第二步: 服务器查找用户私钥(使用提供的公钥)并使用随机32字符字符串(nonce)对其进行散列(sha256) 散列后的nonce和公钥随后存储到本地数组中 然后,服务

我对构建API身份验证非常陌生,所以我想确保我的做法是正确的,因为可能存在我不知道的重大安全缺陷

它基于一个秘密/私钥对,客户机和服务器都知道这个秘密密钥,但显然它从来没有被传递过

对于此方法中的任何反馈、见解或漏洞,我们将不胜感激


第1步:


客户机希望向API发出请求,因此请求服务器提供一个nonce,传递他们的公钥



第二步:


服务器查找用户私钥(使用提供的公钥)并使用随机32字符字符串(nonce)对其进行散列(sha256)

散列后的nonce和公钥随后存储到本地数组中

然后,服务器使用nonce的非散列版本响应客户机



第三步:


客户端从响应中获取nonce,并使用其私钥(客户端在本地拥有)对其进行散列

然后,它向服务器发出请求(以及它想要执行的API任务),并发送其哈希nonce和公钥的版本



第4步:


服务器获取客户端公钥和散列nonce,然后检查本地数组以查看公钥/nonce对是否存在


如果该对存在;身份验证已通过,请求被允许,公钥/nonce对已从本地阵列中删除。

首先,让我说我在安全世界中没有任何凭据。请对我所说的一切持保留态度

一些一般性的想法 似乎你想自己动手,这在任何安全相关领域都是一个坏主意。当野外有几种经过战斗考验的替代品时,情况更是如此

我可以毫不夸张地说出三种广泛使用的API身份验证方法:

  • 基本身份验证。Github将此作为一个选项提供:“用于脚本或测试(即,在完全OAuth将被过度使用的情况下)。”

  • OAuth.Github、Twitter、Facebook、LinkedIn和Google都使用此功能。该协议已详细说明,但对于较小的项目来说可能过于苛刻。多亏了广泛使用的客户端库,实现起来相当容易

  • 基于散列的消息身份验证代码(HMAC)。所有Amazon Web服务都使用此代码。这可能是最不受欢迎的解决方案,因为它在概念上比OAuth简单:客户端使用其私钥对请求进行签名,并在请求中发送签名+公钥。服务器使用客户端发送的公钥查找私钥,然后创建请求的签名。如果签名匹配,则请求有效。必须事先交换公钥和私钥(AWS允许您下载私钥一次)

  • 根据您的描述,HMAC是最接近您所需的候选人

    对你的建议有一些具体的想法
  • 您的算法要求您在服务器上保持状态(提示“本地数组”)。这对于单个服务器来说很好,但是当您进行扩展时,您会做什么呢?当第2步击中一台服务器,第3步击中另一台服务器时,必须共享状态。当然,您可以使用共享数据库(或缓存)或任何东西,但您必须考虑这一点

  • 往返。需要像您建议的那样进行两步身份验证,每个客户端必须为每个(有效负载)请求发送额外的请求(以获取nonce),或者您必须考虑何时在服务器上使对失效HMAC基本上做同样的事情,没有请求开销。

  • 可能的攻击:我可以向您的服务器发送大量的客户端请求。根据您的公钥长度,我可能会提出有效的公钥,并且我可以占用从未用于第二个请求的资源。根据您如何处理(另请参见第1点),我可能会关闭您的服务器


  • 谢谢你的回复-你提出了一些我没有考虑的观点。我会详细地看一下你提到的HMAC方法,因为它看起来和我要找的最接近。如果答案有用,请考虑投票和/或接受它。谢谢没有足够的代表投票-但接受了答案,因为它的帮助!