如何可靠地传递带时间戳的API令牌
我正在从一个应用程序到另一个应用程序进行API调用。我通过传递如何可靠地传递带时间戳的API令牌,api,security,md5,token,Api,Security,Md5,Token,我正在从一个应用程序到另一个应用程序进行API调用。我通过传递md5ed共享机密+时间戳来处理授权 $token = md5( $secret . time() ); 然后在API端点,我像这样检查请求的真实性 if ( md5($shared_secret . time() ) == $token ) ...do stuff 这很有效。但它不像我希望的那样可靠。我怀疑原因是网络延迟(或我的本地主机服务器速度慢),导致时间戳不匹配一秒左右 我以一种懒散的方式解决了这个问题,删除了时间
md5
ed共享机密+时间戳来处理授权
$token = md5( $secret . time() );
然后在API端点,我像这样检查请求的真实性
if ( md5($shared_secret . time() ) == $token )
...do stuff
这很有效。但它不像我希望的那样可靠。我怀疑原因是网络延迟(或我的本地主机服务器速度慢),导致时间戳不匹配一秒左右
我以一种懒散的方式解决了这个问题,删除了时间戳的最后一位数字,从而为我的slowpoke服务器创建了一个长达10秒的窗口来进行调用。然而,我对此并不满意,因为如果电话恰好在第9秒的最后一刻掉了,我会再次遇到同样的问题(在第50秒发送)
必须有更好的方法来做到这一点。它是什么?用一个nonce来代替?将nonce保存到DB或某个持久性存储中,以确保不使用相同的nonce 与您的“第9秒问题”相反,您在秒#######…0到######…9上也有类似的问题,当您切断尾随的0到9时,将散列到相同的值。它将允许在10秒的时间范围内重播 这似乎更像是保证/检查真实性的问题 您必须同时发送明文和散列文本,以便服务器进行检查,但这似乎比时间戳方法好一点
无论哪种方式,仅使用这两个参数,您只能检查它是否是重复请求,而不是验证任何内容。使用时间戳不是正确的方式,因为时间在整个系统中不可靠。也许您可以使用消息的长度/哈希值作为参数。不幸的是,它不会阻止攻击者播放
如果我错了,请纠正我,但似乎您处理的是身份验证(即,发件人就是他们所说的人)而不是授权。我建议您使用SSL/TLS保护传输,以了解传输是否被代理。考虑使用
令牌=时间| | MAC(时间,共享|秘密)
其中| |是串联,MAC是消息身份验证算法,如HMAC,它接受一个密钥和一些数据,并生成一个身份验证标签。在服务器端,检查MAC是否有效,以及时间(以明文形式接收)是否在可接受的窗口内
这比您当前的解决方案(md5的MAC性能较差)更安全,也解决了您的窗口问题
请注意,此方案容易在您允许的错误窗口内受到重播攻击(例如,同一令牌可以在一秒钟的窗口内发送十次,服务器无法判断)。我不确定您建议的解决方案。然而,您似乎误解了什么:时间戳不是用于身份验证的。它用于保护共享的秘密。如果没有它,呼叫很容易被拦截,令牌也会被破坏。有了时间戳,API调用可以被截获,但1(0)秒后该令牌就没用了。有意义吗?我想我专注于这一点:“我像这样检查请求的真实性”我的评论是否澄清了我为什么要包括时间戳?是的。你想要一些寿命短的东西,这样就不能再使用了。看看OAuth协议是如何工作的。如果时间戳不是正确的方式,那么正确的方式是什么?我知道SSL会加密整个呼叫,但这并不是我要问的问题的答案。由于这里不重要的原因,我的系统不能依赖SSL。对不起,编辑了我的帖子-一般认为时间戳是可以减去的,因为它不可靠。你完全正确。我忘了用明文发送时间戳了!我过去就是这样做的,我完全忘记了。我很想听听你对MAC和md5的看法。为什么md5是一个糟糕的选择?(顺便说一句,我在PHP工作)对于问题中的构造类型来说是个问题。例如,根据时间格式和/或收件人在解释时间方面的灵活性,攻击者可能能够使用令牌为将来通过收件人验证的时间创建新令牌。PHP有一个新的功能。当与md5一起使用时,HMAC被认为是安全的,但除非您有特别的理由使用md5,否则我建议您使用sha256。了解PHPHPHHMAC非常好。但是,我不能100%确定如何在我的情况下应用它,因为我没有发送任何加密数据。只有共享的秘密+时间戳。那么这个
hmac('md5','foobar',$secret)
比简单的md5($secret)
更好吗?或者它们是等价的,hmac
的优点是可以选择使用sha256?time | | MAC(time,shared_secret)
其中MAC是hmac-MD5,在php中可能是这样的:$t=time()$str=$t.“:”。hash_hmac('md5',$t,$secret)
。这确实是一款比md5($shared_secret.time())更好的MAC电脑。看起来很棒。谢谢为了让我更好地理解,两者之间有什么区别?为什么后者更好?