使用SHA-1哈希的PKE REST Auth

时间:2014-03-01 11:38:29

标签: api rest authentication public-key-encryption hmac

我正在设计我的第一个RESTful API,并试图弄清楚我将如何验证API调用。我过去曾与Gengo API (dev docs)合作并且运气很好,所以我承认,我的auth设计基于该链接中描述的算法。

要总结他们的进程,要创建有效/经过身份验证的API调用:

  1. 注册一个帐户并生成公钥/私钥集。然后为每个API调用:
  2. 获取正在进行呼叫的UNIX纪元时间戳。
  3. 计算时间戳的SHA-1哈希值“反对”您的私钥。
  4. 确保您的公钥,私钥和计算的哈希(上图)在每次单独的API调用时都显示为3个单独的HTTP参数。
  5. 起初这对我来说有点混乱,但我能够通过他们的API很快地进行身份验证。但是我从来没有完全理解为什么我必须生成这个SHA-1哈希,我不知道他们在服务器端做了什么来实际验证我的API调用。

    现在我正在编写自己经过身份验证的API,我需要了解这些内容。所以我问:

    1. 时间戳及其派生的SHA-1哈希的用途是什么?为什么要求用户在每次API调用时向我发送公钥/私钥都不太安全?
    2. Gengo是否使用API​​身份验证的标准化做法的pubkey + privkey + hashed_timestamp方法?如果是这样,它有名称/算法吗?还有其他同样安全的竞争对手吗?
    3. 我对整个HMAC / SHA-1的东西感到困惑(具体例子见上面的链接)。我一直以为SHA-1是一个单向函数,它将一个字符串变成一个类似于MD5提供的unqiue编码strinig。但在该示例中(请参阅链接),它看起来像是将SHA-1和字符串传递给某些HMAC算法。这个HMAC服务的目的是什么?为什么它需要3个参数(SHA-1,时间戳和私钥)?
    4. 最后,我如何处理服务器端的3个参数(pub键,priv key,哈希时间戳)来执行身份验证?如果我正在设计一个使用pub / priv密钥的系统,那么我会将它们视为用户名/密码组合,并检查数据库以查看该组合是否存在。但是哈希时间戳真的让我不在这里。

2 个答案:

答案 0 :(得分:0)

  

时间戳及其派生的SHA-1哈希的用途是什么?为什么要求用户在每次API调用时向我发送公钥/私钥都不太安全?

要清除您似乎预先存在的任何误解,用户应从不通过网络发送私钥。私钥是保密的。这是您和用户之间共享的秘密。重新阅读Gengo链接,您将看到它仅用作HMAC功能的参数。用户可以找到保护它的方法,但您的API不需要它来验证呼叫。

时间戳有两个目的。首先,它是一个数据,您将获得明文和HMAC。您将使用用户的私钥重新计算HMAC。如果HMAC检查,则意味着不仅时间戳没有被篡改,而且只有知道私钥的人才能发送它。它为该数据提供了完整性和真实性。

如果它是一个简单的SHA1,攻击者可能截获了该消息,更改了时间戳,并重新计算了哈希值。通过使用键控哈希,您可以确保发件人是您认为的人。

时间戳的第二个目的是防止重放攻击。即使使用密钥哈希,攻击者也可能已捕获旧请求并再次发送,可能会触发不需要的操作。如果您的用户散列时间并进行测试并拒绝不合理的旧请求,则可以防止此类重播攻击。

  

这个pubkey + privkey + hashed_timestamp方法Gengo是否正在使用API​​身份验证的标准化做法?如果是这样,它有名称/算法吗?还有其他同样安全的竞争对手吗?

同样,私钥不会通过管道发送。使用HMAC进行API身份验证非常常见。例如,它用于Amazon Web Services。当以Gengo方式使用时,看似公共/私钥对的事实可能令人困惑,它实际上仍然是对称加密,并且私钥被用作共享密钥。

但是我认为在HMAC的数据中包含的不仅仅是时间戳更好。否则,攻击者可能会篡改请求的其他部分。还应包括标头,HTTP谓词和请求内容的哈希值。

另一种方案是使用客户端的私钥来签名(使用私钥加密)一段数据,因此服务器只需要验证它使用客户端的公钥,不需要知道客户端的私钥。仍然需要嵌入时间信息以防止重放。我对这个方案了解不多,首先可能很难可靠地将客户端与给定的公钥链接起来。

  

这是为了什么目的   HMAC服务,为什么它需要3个参数(SHA-1,时间戳   和私钥)?

HMAC是键控哈希。考虑最简单的消息身份验证形式:hash(key + message)。结果发现这不安全(参见length extension attack)并且嵌套结构修复了漏洞。

HMAC是该结构的通用名称:hash(k1 + hash(k2 + message)),其中k1k2是从实际密钥派生的。因此,当我们进行HMAC时,我们需要传递将要使用的实际哈希算法的名称(此处为SHA-1),消息(此处为时间戳)和密钥。

  

最后,我如何处理3个参数(pub键,priv key,hashed   服务器端的时间戳)执行身份验证?如果我是   设计一个只使用pub / priv键的系统,那么我会   将它们视为用户名/密码组合,并检查数据库   看看那个组合是否存在。但是哈希时间戳是   真的把我扔了。

希望现在更加清晰。您使用公钥作为标识符来检索私钥。您使用ts标头并使用私钥重新计算它的HMAC。如果它与发送的hmac标头匹配,则该请求是可信的。您检查实际时间戳,看看它是否是某个攻击者重播的旧请求。如果全部检查,则可以通过呼叫。我认为最好将所有重要信息嵌入HMAC,而不仅仅是时间戳。

答案 1 :(得分:0)

您需要 公钥加密 HMAC,而不是两者。

让我们稍后再回到时间戳,你就会将身份验证与完整性混淆,我们也会在稍后再回过头来。

身份验证:在您的情况下,这是客户端证明服务器的某些秘密的知识。两种常见的方法是通过公钥加密和使用HMAC。

  • PKC:在使用服务之前,会生成公钥/私钥对。客户端有私钥;服务器有公钥。重要提示:私钥永远不会离开客户端。特别是,服务器无权访问私钥。要进行身份验证,客户端会加密一些随机值N(称为nonce),并将N及其加密的表单发送到服务器。服务器使用公钥解密加密的nonce,并确认它等于提供的nonce。这向服务器证明客户端具有私钥。

  • HMAC:客户端和服务器事先同意共享密钥K.要进行身份验证,客户端会创建一个nonce N,计算HMAC(K,N),并将N和HMAC(K,N)发送到服务器。服务器还计算HMAC(K,N),因为它知道共享秘密并且已从客户端接收到N.如果计算和接收的HMAC(K,N)值相同,则服务器知道客户端具有共享密钥K.

与PKC相比,HMAC方法有一个显着的弱点:如果服务器被泄露,那么被攻击者就会获得K的知识,然后可以使用它伪装成客户端。

如果使用PKC,理想情况下在客户端生成密钥对并将公钥发送到服务器。这样,服务器永远不会拥有私钥。

但是,除非通信渠道是保密的(例如使用SSL / TLS),否则两种方法都存在问题:重放攻击。被动观察者可以记录N +加密形式,或N + HMAC(K,N)并将它们重放到服务器。然后服务器会认为观察者是有效的客户端。

两种标准防御措施是:

  • 使用基于时间的随机数。

  • 服务器会记住以前见过的nonce,并拒绝使用以前看过的nonce的新请求。

这就是时间戳的来源,这里有更详细的讨论:Should I sign (with a public/private key) a form based authentication (no SSL)?

完整性:我们已向服务器证明我们是有效的客户,但我们没有对请求本身提供任何保护。攻击者可以在飞行中修改我们的请求:我们正确地进行身份验证,然后执行攻击者的请求而不是客户端的原始请求。

要解决此问题,我们需要保护请求的完整性。我们可以用与上面相同的机制来做到这一点。而不是仅使用随机数(N)或随机数+时间戳,包括加密或散列数据中的整个请求。这里一个重要的考虑因素是加密和散列操作字节,而不是REST请求。因此,您需要一种可靠的方法将REST请求(即HTTP方法,URL,请求参数)转换为字节。这通常被称为“规范化”:客户端和服务器必须以完全相同的方式规范化请求,以便它们在给定请求时加密/散列相同的字节。

整个过程在诸如OAuth之类的标准中被标准化,例如https://dev.twitter.com/docs/auth/authorizing-request

回答您的具体问题:

  1. 时间戳防御重放攻击:被动观察者无法回复客户端的会话。 SHA-1哈希用作HMAC的组件。

  2. 是的,到了一定程度。但我会使用完全成熟的实现,而不是自己动手,比如基于OAuth的东西。

  3. HMAC是一个带键的哈希:它就像一个标准的加密哈希(比如SHA-1,除了你还在哈希中包含一个共享密钥。简单地将密钥连接到被哈希的数据有加密HMAC构造避免的弱点。(https://en.wikipedia.org/wiki/HMAC。)

  4. 如果您正在使用PKC,那么您在服务器上查找客户端的公钥(基于某个客户端ID,客户端的私钥),使用它来解密加密的请求,并验证该请求是否与收到的请求匹配。如果您正在使用HMAC,那么您将查找客户端的共享密钥,规范化请求,计算HMAC(K,R)并验证它是否与收到的HMAC(K,R)匹配。在这两种情况下,您还必须验证时间戳/随机数以防止重放。

  5. 但是:加密规则#1:不要自己滚动。使用已建立的机制,例如OAuth。您可能还想使用SSL / TLS,这样您也可以使用客户端证书作为第三个身份验证选项。如果您使用了那些,那么您也可以依靠SSL / TLS为您提供完整性和重播保护。但是,正确实施SSL / TLS证书验证似乎让很多开发人员感到高兴......