简体   繁体   中英

secure HMAC authorization with changing signature

I have a Rails app that provides a JSON API that is consumed by a python script. Security is important and I've been using HMAC to do it. the rails app and the python script both know the secret key and the signature that they encrypt with it is the URL and the body of the request.

My problem is that the signature of the request doesn't change each time. If it was intercepted then an attacker could send the exact same request with the same digest and I think it would authenticate, een though the attacker doesn't know the secret key.

So I think I need to have something like a timestamp of the request included in the signature - the problem is I don't know how to get at that in python and ruby.

This is my python code:

import hmac
import hashlib
import requests

fetch_path = url_base + '/phone_messages/pending'
fetch_body = '{}'
fetch_signature = fetch_path + ':' + fetch_body
fetch_hmac = hmac.new(api_key.encode('utf-8'), fetch_signature.encode('utf-8'), haslib.sha1).hexdigest()

and this is my ruby code:

signature = "#{request.url}:#{request.body.to_json.to_s}"
hmac_digest = OpenSSL::HMAC.hexdigest('sha1', secret_key, signature)

Question : I need to have something like a timestamp of the request included in the signature

For example:

import hmac, hashlib, datetime

api_key = 'this is a key'
fetch_path = 'http://phone_messages/pending'
fetch_body = '{}'
fetch_data = fetch_path + ':' + fetch_body


for n in range(3):
    fetch_signature = fetch_data + str(datetime.datetime.now().timestamp() )
    fetch_hmac = hmac.new(api_key.encode('utf-8'), fetch_signature.encode('utf-8'), hashlib.sha1).hexdigest()
    print("{}:{} {}".format(n, fetch_signature, fetch_hmac))

Output :

 0:http://phone_messages/pending:{}1538660666.768066 cfa49feaeaf0cdc5ec8bcf1057446c425863e83a 1:http://phone_messages/pending:{}1538660666.768358 27d0a5a9f33345babf0c824f45837d3b8863741e 2:http://phone_messages/pending:{}1538660666.768458 67298ad0e9eb8bb629fce4454f092b74ba8d6c66 

I recommended, to discus Security at security.stackexchange.com .
As a starting point, read: what-is-a-auth-key-in-the-security-of-the-computers

I resolved this by putting the timestamp (seconds since epoch) in the body of the post request, or parameter of the get request. I simply used the timestamp as the signature for encoding, which means the HMAC hash is different for every request that comes in a different second.

Then to prevent an attacker just using a previously seen timestamp I verified on the server that the timestamp is not more than 5 seconds before the current.

An attacker with a really fast turn around of intercepting a communication and sending an attack could still get through, but I couldn't drop the timeout below 5 seconds because it's already getting some requests timing out.

Since the whole thing is done under SSL I think it should be secure enough.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM