2015-05-22 50 views
2

我正在使用Django为移动应用程序实现一项Web服务。我决定使用Hash-MAC来认证请求(没有誓言,没有https),但挑战是我应该如何使用共享密钥?使用Django进行HMAC身份验证 - 共享密钥

首先我考虑使用用户的密码,但它需要在服务器端数据库中以纯文本格式存储密码。我想到的另一个解决方案是在移动应用程序中进行salting和散列密码,就像django auth应用程序所做的那样,以便在客户端计算散列密码。

  1. Django用作盐吗?他们是“秘密的”吗?将它们作为纯文本发送给用户有任何问题吗?我们不需要将盐作为一般的“秘密”,但是Django可能会使用一些应该保密的东西,我不知道,它是关于django如何实现这一点的。

  2. 用户必须知道他们的salt来计算散列密码,所以服务器应该为他们提供它。对手可以要求所有用户使用盐类,最终可以得到所有的盐类(即使在某个时间段内某人可以要求的次数有限制)。尽管盐不是秘密的,但我猜想他们的“全部”都是危险的。 (或者可能是我过分担心安全!)

请求格式:

HTTP request header: 
x-mac-digest: 1d186b9c0fd5cd393f23623f0d167f7b17ac7d1cd74d8442647991d61e756c19 

HTTP request body: 
{ 
    "username": "mjafar", 
    ... rest of request in json 
} 

身份验证请求(简化​​):

hash_digest = request.META['HTTP_X_MAC_DIGEST'] 
request_body = request.body.decode('utf-8') 
request_json = json.loads(request_body) 

user = UserModel.objects.get(username=request_json['username']) 
sharedKey = getSharedKey(user) # What should it return? 

hash = hmac.new(sharedKey, request_body, hashlib.sha256).hexdigest() 
if hash != hash_digest: 
    return HttpResponseBadRequest('MAC authentication failed') 
+0

另外,这里有什么问题,你想做什么? – Ahmed

+0

@ Ahmed我试图验证Web服务器的请求,而不用纯文本发送密码或访问令牌。 –

+0

什么发送到服务器:(消息,用户名,散列(消息||密码)) –

回答

1

HMAC用于验证消息的块。它用于验证密码块/传输过程中文本未被更改。您将需要使用非对称加密(RSA,DH,..等)来传输您的共享密钥。

使用纯文本而不使用数字签名是没有用的。你会很容易受到MITM攻击。除非您设法在没有互联网的情况下将移动应用上的共享密钥(GSM SIM卡在SIM卡内部共享密钥并用于加密GSM呼叫)。

Django使用随机函数来生成它的secret_key。 Linux上的随机函数会调用/ dev/urandom,在windows上将调用与之相当的内容。

在你的情况下,创建一个休息api来创建一个用户名和密码,然后返回一个散列值用于访问你的视图。

如果要计算自定义哈希值,你可以调用make_password功能,并直接在密码属性将它保存在用户

阅读:https://docs.djangoproject.com/en/1.8/topics/auth/passwords/

例子:Django make_password too slow for creating large list of users programatically

+0

这回答我的第一个问题(upvoted),如果你可以回答第二个问题(甚至在评论中),这将是如此有用 –

+0

你可以通过DH转移盐,然后在客户端和服务器。但是,您需要了解您的邮件将在网络中看到,如果您未使用数字签名,则有可能在第一次传输盐时执行MITM攻击。 – Ahmed

+0

盐首次在手机和服务器中传输。如果电话用户登录或在新电话上安装应用程序,请求用户提交密码,然后用盐进行散列,如果正确,则通过DH – Ahmed

相关问题