我一直在阅读这里有很多关于使用api密钥,令牌,hmac来保护web api并且找不到我想要的答案的问题。
我正在开发一个包含互联网和内联网站点,web api和Android / iOS应用程序的MVC4 Web应用程序项目。
我的应用程序和其他人都不会使用Web API,因为它将访问敏感数据。
保护此API的最佳方法是什么,只有我的应用才能使用它?看起来像这么简单的请求是非常难以开始的。
我已经使用HMAC和其他一些人查看了这里的帖子,但是没有一个听起来像他们适合这里,更可能是我只是遗漏了一些东西。
HMAC是可行的方式还是客户证书更适合这种情况?
我应该使用SSL和某种API密钥吗?
我知道这个问题有点模糊,我一直盯着它看了一个多小时试图弄清楚我在想什么,所以我想我会发布它并在需要时更新......: (
我很乐意根据要求提供更多细节。
答案 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相同。请参阅this和this。这将允许在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)
现在您拥有了发送到服务器所需的一切:
在标题中,您还需要发送otp
,salt
和device_token
!
在服务器上,您将执行标记为B1-3
的相同步骤,并将您的哈希结果与客户端提供的结果进行比较。在那之后你必须确保你禁止'这个salt
的{{1}}是为了避免重播攻击。
此方法仍存在一个缺陷,但攻击者需要做更多工作:
他们可以在您编译的代码中找到您的device_token
。
答案 3 :(得分:1)
我正在开展一个类似的项目,我为每个访问我的API的用户或客户端应用程序分配了唯一的API密钥。我不是安全专家,但我建议您使用SSL并为Android和iOS应用程序生成唯一的API密钥。使用SSL,传输到API的数据将被加密和保护。