如何使用Android / iOS应用程序保护我的Web API - MVC4

时间:2013-06-19 17:02:05

标签: asp.net-mvc asp.net-mvc-4 asp.net-web-api

我一直在阅读这里有很多关于使用api密钥,令牌,hmac来保护web api并且找不到我想要的答案的问题。

我正在开发一个包含互联网和内联网站点,web api和Android / iOS应用程序的MVC4 Web应用程序项目。

我的应用程序和其他人都不会使用Web API,因为它将访问敏感数据

保护此API的最佳方法是什么,只有我的应用才能使用它?看起来像这么简单的请求是非常难以开始的。

我已经使用HMAC和其他一些人查看了这里的帖子,但是没有一个听起来像他们适合这里,更可能是我只是遗漏了一些东西。

HMAC是可行的方式还是客户证书更适合这种情况?

我应该使用SSL和某种API密钥吗?

我知道这个问题有点模糊,我一直盯着它看了一个多小时试图弄清楚我在想什么,所以我想我会发布它并在需要时更新......: (

我很乐意根据要求提供更多细节。

4 个答案:

答案 0 :(得分:2)

为每个应用生成一个密钥,让他们将每个请求中的密钥作为令牌传递。然后,您的服务器可以验证密钥并验证请求。

查看ASP.NET站点中的Basic Authentication模块。该示例使用“基本”作为授权方案,但您可以使用“令牌”进行更改。

private static void OnApplicationAuthenticateRequest(object sender, EventArgs e)
    {
        var request = HttpContext.Current.Request;
        var authHeader = request.Headers["Authorization"];
        if (authHeader != null)
        {
            var authHeaderVal = AuthenticationHeaderValue.Parse(authHeader);

            // RFC 2617 sec 1.2, "scheme" name is case-insensitive
            if (authHeaderVal.Scheme.Equals("token",
                    StringComparison.OrdinalIgnoreCase) &&
                authHeaderVal.Parameter != null)
            {
                AuthenticateUser(authHeaderVal.Parameter);
            }
        }
    }

准备好Basic Auth模块后,您只需使用Authorize属性修饰任何操作或控制器,它就会将请求转发给Basic Auth处理程序。

namespace webapi.Controllers
{
     [Authorize]
     public class SensitiveDataController : ApiController
     {
       ...
     }
}

在使用基本身份验证时,必须使用SSL,因为您的密钥将以纯文本形式传输。

答案 1 :(得分:2)

您可以使用FormsAuthentication。加密票证并确保两个配置文件中的machineKey相同。请参阅thisthis。这将允许在web app和api之间共享相同的用户凭据。在这种情况下,ASP.NET FAM模块将建立身份。

对于api密钥,请查看hawk scheme。它使用共享对称密钥。但是,Hawk是功能完备的,直到它达到1.0版本,它可能会改变。尽管如此,它将为您提供实施基于HMAC的安全性的好主意。我有一个针对Hawk的.NET实现here。还有一个来自Pablo。在这种情况下,您需要编写一个消息处理程序来为使用的应用程序建立标识。

答案 2 :(得分:2)

在高流量应用的一般情况下,上述所有答案都存在许多攻击者可以轻易利用的漏洞: 使用监狱破解iPhone,您可以破解SSL - 而不是服务器,但是当他们在手机上安装了您的应用程序时,他们至少可以分析您发送的软件包。

避免这种情况的最佳方法(在我看来)是使用'准​​时密码' - 实时密码。

如何生成这些一次性密码?

A1。为每个设备获取device_identifier(这也可以是任意随机数,但您应避免与其他设备发生冲突'标识符)

A2。有api_key,您将用于散列

现在,如果您想将包发送到您的api,请执行以下操作:

B1。构造您的普通包,这是一些json有效负载的示例:

var payload = {"hello":"world"}

B2。使用您最喜欢的散列函数哈希您的var hashed_payload = hash(payload)

B3。生成此包的​​一次性密码:

var otp = hash(salt & hashed_payload & device_token & api_key)

现在您拥有了发送到服务器所需的一切:

在标题中,您还需要发送otpsaltdevice_token

在服务器上,您将执行标记为B1-3的相同步骤,并将您的哈希结果与客户端提供的结果进行比较。在那之后你必须确保你禁止'这个salt的{​​{1}}是为了避免重播攻击。

此方法仍存在一个缺陷,但攻击者需要做更多工作: 他们可以在您编译的代码中找到您的device_token

答案 3 :(得分:1)

我正在开展一个类似的项目,我为每个访问我的API的用户或客户端应用程序分配了唯一的API密钥。我不是安全专家,但我建议您使用SSL并为Android和iOS应用程序生成唯一的API密钥。使用SSL,传输到API的数据将被加密和保护。