python3 api加密

背景需求

写了一个牛逼的接口

def server_info(request):
    result = {"isSuccess": True, "message": 3}
    return HttpResponse(json.dumps(result))

突然有一天这个接口变成了超级牛逼的接口,需要被其它系统调用了,安全的需求出现了。

加密原理

1 首先双方约定一个 TOKEN 。这个TOKEN说白了就是一长串没有规则的数字 + 字母 + 特殊字符的组合。

2 明文传输肯定不行啊,选了个主流的sha1,但是每次都传一样的加密信息早晚是要被别人搞啊。
要不断变化才行,时间戳这个时候出场了,主角来了: sha1(token + timestamp)|timestamp. (|timestamp 是干嘛用的 有小伙伴猜到了么?)

用户传 sha1(token + 用户的timestamp)|用户的timestamp 这个信息给我,我拿到数据后从 “|”切割开来备用,我也来加密一下sha1(token + 用户的timestamp)。用我加密的数据对比一下”|”前面加密的数据就知道 用户传过来的token是不是你和用户约定好的那个了。

3 为了更加安全 我们还设置了过期时间。

代码实现

写了一个那么牛逼的接口代码 有办法不去修改接口代码就实现接口加密呢? 然后有啦,装饰器这个时候派上用场了。

装饰器代码

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from django.shortcuts import HttpResponse
from api import Securty
def api_auth(func):
    def wrapper(request):
        securty_key = request.GET.get('securtykey',None)
        if not securty_key:
            return HttpResponse('Unauthorized')
        if not Securty.auth_api_vaild(securty_key):
            return HttpResponse('Unauthorized')
        return func(request)
    return wrapper

加密逻辑实现

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import time
import hashlib

WEBAPI_TOKEN = "**********************"
expires_time = 180

def auth_api_vaild(data):
    try:
        encryption,time_span = data.split('|')
        time_span = float(time_span)
        if (time.time() - time_span) > expires_time:
            return False
        str_key = ('%s|%f' % (WEBAPI_TOKEN, time_span)).encode('utf-8')
        hash_obj = hashlib.sha1()
        hash_obj.update(str_key)
        if hash_obj.hexdigest() == encryption:
            return True
        else:
            return False
    except Exception as e:
        print(e)
    return False

创建测试api_key

import hashlib
import time

WEBAPI_TOKEN = "****************"

def create_api_key():
    hash_obj = hashlib.sha1()
    key = WEBAPI_TOKEN
    time_span = time.time()
    str_key  = ('%s|%f' %(key,time_span)).encode('utf-8')
    hash_obj.update(str_key)
    encryption = hash_obj.hexdigest()
    result = '%s|%f'%(encryption,time_span)
    return result

验证结果

先用 create_api_key函数 跑一个测试用的 api_key

**************ceb8eaf0da77c7f98f121878|1482846167.177168

请出 postman