【问题标题】:Using HMAC with Web App and API将 HMAC 与 Web 应用程序和 API 一起使用
【发布时间】:2013-08-31 11:13:33
【问题描述】:

我一直在尝试为我的 API 实施一个授权系统,该系统将能够用于 Web 应用程序。我看过三足 OAuth 以及签名验证,但我对 OAuth 并不感兴趣。我正在测试的方法可以找到here。 它使用 HMAC 来授权签名请求,类似于 Amazon Signature。我刚刚在这里拼凑了一个工作示例。没什么特别的。只是概念验证。

客户端使用 CryptoJs 和 JQuery



   //Dummy credentials
    var username = 'username';
    var password = 'password';

    //first create the key and store it in memory for the duration of the app
    var KEY = CryptoJS.SHA512(username + "." + password).toString();
    var url = "http://127.0.0.1/whisppa/api";

    //setup the parameters that will be sent to the server
    var params = 
    {
        "user" : username,
        "requested_url" : CryptoJS.MD5(url).toString(),//hash the url to make it shorter
        "signature_version" : "1.0",
        "time" : 0
    }

    //get all parameters and sort them
    var props = [];
    for(var prop in params)
    {
        props.push(prop);
    }
    props.sort();

    //concatenate the parameters as a parameter string and set the time value
    var param_string = "";
    for(var prop in props)
    {
        prop = props[prop];
        if(prop == "time")
        {
            params.time = Math.round(new Date() / 1000);
        }

        param_string += prop + "=" + params[prop] + "&"; 
    }
    param_string = param_string.substring(0, param_string.length - 1);

    //generate the hmac of the request to be set in the header
    var hmac = CryptoJS.HmacSHA512(param_string, KEY).toString();

    //make the request
    $.ajax({
        type:"GET",
        beforeSend: function (request)
        {
            request.setRequestHeader("Auth-KEY", hmac);
        },
        url: url,
        data: "params=" + escape(JSON.stringify(params)),
        processData: false,
        success: function(msg) {
            $('body').html(msg);
        }
    }); 

服务器使用 slim php 框架和 php 5.4。

         


    //define the time before the app starts
    define('TIME', round(microtime(true)));

    $headers = getallheaders();

    //just make a few checks here to ensure necessary params are set
    if(!isset($_GET['params']) || !isset($headers['Auth-KEY']))
    {
        $app->halt(400);
    }
    //get the parameters from the get string
    $params = json_decode($_GET['params']);

    //make some more checks for important parameters
    if(!isset($params->time) || !isset($params->user))
    {
        $app->halt(400);
    }

    //get the parameters and sort them
    $properties = get_object_vars($params);
    ksort($properties);

    //concatenate the parameters as a parameter string
    $param_string = '';
    foreach($properties as $prop => $value)
    {
        $param_string .= $prop . '=' . $value . '&'; 
    }
    $param_string = substr($param_string, 0, strlen($param_string) - 1);

    //in reality, fetch the user from the database
    $password = 'password';

    //create the hash and then generate the HMAC
    $KEY = hash('SHA512', $params->user . '.' . $password);
    $Auth_KEY = hash_hmac('SHA512', $param_string, $KEY);

    //verify the request
    if($Auth_KEY == $headers['Auth-KEY'])
    {
        $app->halt(401);
    }

    //verify the time
    if(TIME - $params->time > 60)
    {
        $app->halt(408);
    } 

    //TODO: verify the requested url matches the current url

显然,这有问题。 我能看到的是

  1. 如何在服务器端存储用户数据。我无法存储明文密码,无法存储散列密码,存储用户密钥是自找麻烦。我似乎无法解决这个问题。

  2. 是否可以在应用程序在内存中运行时存储密钥客户端以使其无法获取?显然,使用诸如 firebug 之类的工具或 chrome 和 firefox 附带的 webdev 工具,您可以得到它。但是是否有可能将它嵌套在代码中如此深,甚至在匿名函数中,这样你就无法轻易获得它。不过我对此并不十分担心,因为它将是我自己的应用程序正在运行。

  3. 适用于请求的超时时间是多少?

  4. 是否有我看不到的明显孔洞?可能是注意力不集中造成的。

谢谢。

编辑

正如我所说,这只是一个证明,我忘了添加请求方法/动词也会添加到哈希中。

This answer似乎掌握了密码存储的答案,但不清楚如何使用api keys/share secret。

编辑 2

我在这里看到的另一个问题是允许用户在其他消费者应用程序上输入他们的密码。一个好的解决方案是使用某种 API 密钥或共享密钥,但是对此有什么想法吗?

【问题讨论】:

    标签: php api security oauth hmac


    【解决方案1】:

    阅读这篇文章Javascript Cryptography Considered Harmful,我决定简单地使用 SSL。 API 还将使用访问密钥和随机数。

    【讨论】:

      猜你喜欢
      • 2021-11-16
      • 1970-01-01
      • 2013-08-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多