代码之家  ›  专栏  ›  技术社区  ›  Peter Sankauskas

API认证设计与可编程性

  •  8
  • Peter Sankauskas  · 技术社区  · 15 年前

    问题:这个API认证技术容易被黑客攻击吗?

    apiKey = "123456789"
    apiCallId = "1256341451"
    apiSecret = "67d48e91ab2b7471d4be2a8c2e007d13"
    sig = md5(apiKey + apiCallId + apiSecret) = 09c297a354219f173bfc49c2e203ce03
    

    哪里

    • apiKey :用户的某个唯一标识符
    • apiCallId :值必须递增的唯一整数(例如,Unix时间戳)
    • apiSecret :只有用户知道的字符串,而US-未传入URL
    • sig :“unackable”此API调用的签名-MD5哈希

    示例API调用:

    http://api.domain.com/?apiKey=123456789&apiCallId=1256341451&sig=09c297a354219f173bfc49c2e203ce03&param1=x&param2=y
    

    此API不需要会话,也不是为第三方代表用户使用而设计的。相反,它将由用户自己使用。

    我真的很喜欢这个简单。要求 阿皮卡里德 独特且不断增加意味着重复使用 SIG 不可能,所以我觉得它是安全的(防止重播攻击),但我不是专家。

    其他API在计算 SIG 但是我不明白为什么在包括 阿皮卡里德 .

    在实施和发布之前,请先尝试破解。

    我欢迎任何反馈、建议和安全教育。

    4 回复  |  直到 15 年前
        1
  •  13
  •   Jack Lloyd    15 年前

    除了不检查参数(这将是一个相当大的问题)之外,您所做的似乎相当理智。

    与你的设计非常相似的东西,复制它可能是明智的,是 Amazon Web Services Request Authentication Scheme

    尤其要确保参数的编码方案是明确和可逆的;Amazon screwed this up 在某一时刻。从他们的错误中吸取教训。:)

    从密码学上讲,您所做的工作不是称为签名,而是消息身份验证代码(MAC)。任何共享密钥的人都可以创建和验证MAC(通常为DSA或RSA等公钥方案保留术语“签名”)。MD5(msg k)是一个已知且相当健全的mac;我不确定您是意外还是故意漏掉了它,但表面上看来等效的方法md5(k msg)是非常不安全的,因为MD5(以及大多数其他哈希函数)的设计方式上的一个奇怪之处意味着,如果您知道h(m),您可以很容易地为任何m2计算h(m m2)-所以我如果您使用的是MD5(k param1=5),有人可以将其从导线上拔下,然后创建MD5(k param1=5,param2=666)。(这可能比你感兴趣的技术性更强,但这被称为 length extension property )

    然而,虽然MD5(k msg)可能是“好的”,但最好使用像hmac这样的东西,因为它实际上是作为mac设计的。MD5有很多问题,但没有直接影响到它作为Mac的使用(然而-MD4已经这样被打破)。因此,对于将来的校对(和审核校对),请使用带有SHA-1或SHA-256的HMAC。即使您不想拉入加密库,HMAC也非常简单,并且有已知的值可用于 SHA-1 SHA-2 所以你可以检查你的代码。

        2
  •  2
  •   erickson    15 年前

    不。其他参数(示例中的param1和param2)的完整性不受保护。攻击者可以拦截该呼叫,并在转发之前根据自己的喜好更改这些呼叫。这个 apiCallId 只防止重播,而不是更改第一个调用。

    我不是专家。如果我立即看到,可能还有其他问题潜伏着。

        3
  •  0
  •   Faisal Abid    15 年前

    好吧,假设我知道这个秘密,那么我就可以生成信号并传递它。对我的一家初创公司所做的就是让sig依赖于其他参数,以及一个requestID(uuid)和timestamp,从而进一步获取sig参数,并存储该uuid(几个小时的安全原因来拒绝黑客一次又一次地调用同一个函数)。这样您就不能再次调用同一个调用,您必须生成一个新的uuid,如果黑客替换参数中的uuid,那么sig将失效,并且他不知道如何生成sig,因为除了secret之外,我们还基于长度为30个字符的内部密钥生成签名。所以本质

    MD5(参数的字母列表+ apikey+callid+secert键+ 一些纵向的)

    不确定我是否回答了您的问题,但这是另一种为API做安全性的方法

        4
  •  0
  •   Henri    15 年前

    我建议在这种情况下使用数字签名,因为它们更合适。例如,apikey的数字签名就足够了。你甚至不需要这些秘密和杂碎。您只需要确保数字签名保持私有(就像MD5散列)。

    如果你想防止重播攻击,你需要在每个请求中都有某种随机性。所以我建议如下:

    服务器->API:nonce(=一些随机数)

    api->服务器:enc(nonce+数字签名)

    这是用服务器的公钥加密的,数字签名用服务器的私钥放置。

    现在你不能有重播攻击。然而,仍然存在一个中间人攻击的问题,但解决这个问题并不是那么简单(但相当可行)。因此,根据您想要/需要的安全级别,您可以调整您的技术措施。