Web API安全性

Mic*_*l M 14 php security authentication api

我被要求为应用程序编写Web API(pc可执行文件,而不是web-app),允许发送电子邮件.
用户点击某些内容,该应用与API通信,生成电子邮件并将其发送出去.

我必须确保没有人可以访问API,所以我需要进行某种身份验证,我不知道如何正确地进行身份验证.

将有更多应用程序访问API.

首先想到的是 - 发送用户名和密码,但这并不能解决问题.因为如果有人反编译应用程序,他们将拥有请求URL和变量,包括用户/密码,或者只是它可以被嗅探.

所以...我有什么选择?

我相当肯定安全连接(SSL)目前不可用,但是,这对我反对反编译问题无效,是吗?


编辑

我最初没有说过,但不会要求用户输入用户名/密码.这是必须进行身份验证的应用程序,而不是应用程序的用户.

zom*_*bat 20

软件的分发确实是问题的症结所在.散列用户名和密码并将其存储在软件中并不比存储未散列值更有用,因为任何一个都可以访问API服务器.如果您要为用户实现用户名和密码,我认为您可以将其用作API控件的前置光标,而无需将值存储在软件本身中.让我分两部分来描述这一点.

请求签名

用于API请求验证的最常用方法是请求签名.基本上,在将请求发送到API服务器之前,会对请求中的参数进行排序,并将唯一键添加到组合中.然后使用整个批次生成一个哈希值,该哈希值将附加到请求中.例如:

public static function generateRequestString(array $params, $secretKey)
{
    $params['signature'] = self::generateSignature($params, $secretKey);
    return http_build_query($params,'','&');
}

public static function generateSignature($secretKey, array $params)
{
    $reqString = $secretKey;
    ksort($params);
    foreach($params as $k => $v)
    {
        $reqString .= $k . $v;
    }
    return md5($reqString);
}
Run Code Online (Sandbox Code Playgroud)

您可以使用上面的代码创建一个API请求查询字符串,只需使用generateRequestString()您想要发送的所有参数的数组调用该方法即可.秘密密钥是为API的每个用户唯一提供的.通常,您将用户ID与签名一起传递给API服务器,API服务器使用您的ID从本地数据库获取您的密钥,并以与构建它相同的方式验证请求.假设密钥和用户ID是正确的,该用户应该是唯一能够生成正确签名的用户.请注意,密钥永远不会在API请求中传递.

不幸的是,这需要每个用户都有一个唯一的密钥,这对您的桌面应用程序来说是一个问题.这让我走向第二步.

时间钥匙

因此,您无法使用应用程序分发密钥,因为它可以被反编译,并且密钥会丢失.为了反击,你可以制作非常短暂的密钥.

假设您已实现了要求用户输入用户名和密码的桌面应用程序的一部分,您可以让应用程序向您的服务器执行身份验证请求.在成功进行身份验证后,您可以返回带有响应的临时密钥,然后桌面应用程序可以在授权会话的生命周期内存储该临时密钥,并用于API请求.因为您提到您不能使用SSL,所以此初始身份验证是最容易受到攻击的部分,您必须承受一些限制.

Andy E建议的文章是一个很好的方法(我投票了).它基本上是一个握手,可以建立一个可以用来进行身份验证的短期密钥.相同的密钥可用于签名散列.你也可以抓住机会,只是发送未加密的用户名/密码并获得一个临时密钥(它只会发生一次),但你必须知道它可能被嗅到.

摘要

如果您可以建立临时会话密钥,则不必在客户端程序中存储任何可以反编译的内容.一次发送到您的服务器的用户名/密码应足以确定.拥有该密钥后,您可以使用它在桌面应用程序中创建请求,并验证API服务器上的请求.

  • +1 - 虽然我的确有评论:"哈希用户名和密码并将它们存储在软件中并不比存储未散列的值更有用,因为任何一个都可以访问API服务器." 虽然这与提问者无关(在编辑时),但是如果某人确实设法获取哈希值,那么他们只能**访问API而不是用户的前端帐户或甚至网络上的其他服务 - 因为许多人对不同的网站使用相同的密码.因此,将密码存储为纯文本仍然是明智之举. (6认同)

Ore*_*zor 8

我建议你查看OAuth.它绝对可以帮助您解决安全问题,授权工具可以访问您的API.

http://oauth.net