Authentication 使用HMAC的API身份验证

Authentication 使用HMAC的API身份验证,authentication,hash,oauth-2.0,slim,hmac,Authentication,Hash,Oauth 2.0,Slim,Hmac,我正在寻找一种体面的身份验证方法,以便在编写简单的API以供内部系统使用时使用。关于堆栈溢出的其他问题建议使用HMAC以及教程的链接,我继续并决定实现这些链接 设置此项后,我意识到我不确定这对实际身份验证有多重要。使用的教程列出了客户端上从未在服务器端代码中使用的公共哈希。它只是将内容和私有哈希值散列在一起,并在服务器上进行比较。由于这都是通过头传递的,我想知道这到底有多安全?publicHash值的用途是什么,因为它似乎没有被使用 客户: <?php $publicHash = '34

我正在寻找一种体面的身份验证方法,以便在编写简单的API以供内部系统使用时使用。关于堆栈溢出的其他问题建议使用HMAC以及教程的链接,我继续并决定实现这些链接

设置此项后,我意识到我不确定这对实际身份验证有多重要。使用的教程列出了客户端上从未在服务器端代码中使用的公共哈希。它只是将内容和私有哈希值散列在一起,并在服务器上进行比较。由于这都是通过头传递的,我想知道这到底有多安全?publicHash值的用途是什么,因为它似乎没有被使用

客户:

<?php

$publicHash = '3441df0babc2a2dda551d7cd39fb235bc4e09cd1e4556bf261bb49188f548348';
$privateHash = 'e249c439ed7697df2a4b045d97d4b9b7e1854c3ff8dd668c779013653913572e';

$content = json_encode( array( 'test' => 'content' ) );

$hash = hash_hmac('sha256', $content, $privateHash);

$headers = array(
    'X-Public: '.$publicHash,
    'X-Hash: '.$hash
);

$ch = curl_init('http://domain.com/api2/core/device/auth');
curl_setopt($ch,CURLOPT_HTTPHEADER,$headers);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
curl_setopt($ch,CURLOPT_POSTFIELDS,$content);

$result = curl_exec($ch);
curl_close($ch);

echo "RESULT\n======\n".print_r($result, true)."\n\n";

?>

我认为你发布的文章使用了术语
hash
,让人感到困惑。在文章中,
$publicshash
是用户名,
$privateHash
是用于对有效负载进行签名的密钥

换句话说,正如文章所说,
X-Public
头的值应该用于从数据库查询特定于用户的密钥。然后使用该密钥从有效负载创建哈希。然后将该散列与
X-hash
头的值进行比较

如果值匹配,则可以确保有效负载未被篡改和/或有效负载的发送方知道密钥

这种方法不是无状态的。它要求您为每个请求点击数据库,以找出当前用户的密钥。如果您的客户端不受信任(即启用JavaScript的浏览器),这也有点问题。但对于机器对机器的通信来说效果很好

可供替代的 您可能需要查看名为的文章。JSON Web令牌提供无状态解决方案。它们也是防篡改的,因为令牌是用HMAC签名/散列的

function auth()
{
    $app = \Slim\Slim::getInstance();

    $request = $app->request();
    $publicHash = $request->headers('X-Public');
    $contentHash = $request->headers('X-Hash');
    $privateHash = 'e249c439ed7697df2a4b045d97d4b9b7e1854c3ff8dd668c779013653913572e';
    $content = $request->getBody();

    $hash = hash_hmac('sha256', $content, $privateHash);

    if ($hash == $combinedHash)
    {
        $data = array('status' => "success");
        response($data);
    }
    else
    {
        $data = array('status' => "failed");
        response($data);
    }
}