API验证插件

2021-05-08 00:28

阅读:639

前言

如果在访问某WebAPI过程中request信息被他人截获,若是get请求获取数据还好,如果是post提交数据,势必威胁数据安全,所以对于一个对安全性要求较高的API来说,对每个请求做身份验证显得尤为重要;

 

 

防范策略解析

策略1

客户端发送http请求访问API时,在请求头里设置一个双方约定好的key;

知识点:

1、如果给Django程序发送请求头,headers携带内容包含下滑杠 _,Django会不认识;

2、客户端 auth-api ----->服务端 转换成 ‘HTTP_AUTH_API‘格式

3、服务端获取clent_key=request.META.get(‘HTTP_AUTH_API‘)

客户端

技术分享技术分享
import  requests
key=sssdkjrjefjewfakfhkj
respose=requests.get(url=http://127.0.0.1:8000/test.html/,headers={auth-api:key}).text
#如果给Django程序发送请求头,如果headers里面的内容使用下滑杠 _,Django会不认识;
#auth-api  -----> 转换成 ‘HTTP_AUTH_API‘格式
#服务端获取clent_key=request.META.get(‘HTTP_AUTH_API‘)
print(respose)
View Code

服务端

技术分享技术分享
def test(request):
    key=sssdkjrjefjewfakfhkj
    clent_key=request.META.get(HTTP_AUTH_API)
    if clent_key == key:
        return HttpResponse(你得到我了)
    else:
        return HttpResponse(休想)
View Code

 

漏洞:虽然双方约定好了key,但是请求头依然会被截获到;

 

策略2

1.key+当前客户端时间戳 组成1个MD5加密字符串

2.MD5加密字符串|当前时间戳 组成1串密码,hearder携带

3.服务端接收到客户端发送的那1串密码,split 出客户端时间

4.来着客户端时间+服务端key做MD5加密还原,对比客户端和服务端

 

客户端

技术分享技术分享
import  requests
import time
import hashlib
key=sssdkjrjefjewfakfhkj
ctime=str(time.time())
def MD5(arg):
    hs=hashlib.md5()
    hs.update(arg.encode(utf-8))  #python3加密使用字节类型
    return hs.hexdigest()


new_key=%s|%s % (key,ctime)  # sssdkjrjefjewfakfhkj | 时间戳
md5_str=MD5(new_key)
auth_api_val=%s|%s%(md5_str,ctime)  #d0e0ca7d1f8f72d60715696d4baac3b2(key和时间戳加密后的结果)| 时间戳
print(md5_str)
respose=requests.get(url=http://127.0.0.1:8000/test.html/,headers={auth-api:auth_api_val}).text
print(respose)
View Code

服务端

技术分享技术分享
import hashlib
import time

def MD5(arg):
    hs = hashlib.md5()
    hs.update(arg.encode(utf-8))  # python3加密使用字节类型
    return hs.hexdigest()

def test(request):
    key=sssdkjrjefjewfakfhkj
    auth_api_val=request.META.get(HTTP_AUTH_API)  #052dd27c130f4b9b5a8a4ec4b243962d | 1507374976.4620001
    client_md5_str,client_ctime =auth_api_val.split(|,maxsplit=1)
    server_md5_str=MD5(%s|%s%(key,client_ctime))

    if client_md5_str== server_md5_str:
        return HttpResponse(你得到我了)
    else:
        return HttpResponse(休想)
View Code

 

漏洞:折腾了半天虽然可以动态加密,但依然可以获取到,且客户端会生成很多加密字符串,黑客获取任意一个都可以访问到API

 

策略3

 

1.key+当前客户端时间戳 组成1个MD5加密字符串

2.MD5加密字符串|当前时间戳 组成1串密码,hearder携带

3.服务端接收到客户端发送的那1串密码,split 出客户端时间

4.来着客户端时间+服务端key做MD5加密还原,对比客户端和服务端是否相等

5.动态密码有时间限制,超过5秒失效

 

客户端

技术分享技术分享
import  requests
import time
import hashlib
key=sssdkjrjefjewfakfhkj
ctime=str(time.time())
def MD5(arg):
    hs=hashlib.md5()
    hs.update(arg.encode(utf-8))  #python3加密使用字节类型
    return hs.hexdigest()


new_key=%s|%s % (key,ctime)  # sssdkjrjefjewfakfhkj | 时间戳
md5_str=MD5(new_key)
auth_api_val=%s|%s%(md5_str,ctime)  #d0e0ca7d1f8f72d60715696d4baac3b2(key和时间戳加密后的结果)| 时间戳
print(md5_str)
respose=requests.get(url=http://127.0.0.1:8000/test.html/,headers={auth-api:auth_api_val}).text
print(respose)
View Code

服务端

技术分享技术分享
def test(request):
    server_float_ctime=time.time()
    key=sssdkjrjefjewfakfhkj
    auth_api_val=request.META.get(HTTP_AUTH_API)  #052dd27c130f4b9b5a8a4ec4b243962d | 1507374976.4620001
    client_md5_str,client_ctime =auth_api_val.split(|,maxsplit=1)
    client_float_ctime=float(client_ctime)

    if client_float_ctime+5  server_float_ctime:
        return HttpResponse(想要破解密码最在5秒之内)

    server_md5_str = MD5(%s|%s % (key, client_ctime))
    if client_md5_str== server_md5_str:
        return HttpResponse(你得到我了)
    else:
        return HttpResponse(休想)
View Code

 

漏洞:虽然加密字符串有了时间限制,但时间就是漏洞

 

 

策略4

 

1.key+当前客户端时间戳 组成1个MD5加密字符串

2.MD5加密字符串|当前时间戳 组成1串密码,hearder携带

3.服务端接收到客户端发送的那1串密码,split 出客户端时间

4.来着客户端时间+服务端key做MD5加密还原,对比客户端和服务端是否相等

5.动态+加密字符串+时间限制,超过5秒失效

6.记录最近5秒访问客户端的加密字符串,如果当前客户端使用的字符串存在记录中,说明是窃取(因为正常用户每次,访问API会携带不同的加密字符串)

客户端

技术分享技术分享
import  requests
import time
import hashlib
key=sssdkjrjefjewfakfhkj
ctime=str(time.time())
def MD5(arg):
    hs=hashlib.md5()
    hs.update(arg.encode(utf-8))  #python3加密使用字节类型
    return hs.hexdigest()


new_key=%s|%s % (key,ctime)  # sssdkjrjefjewfakfhkj | 时间戳
md5_str=MD5(new_key)
auth_api_val=%s|%s%(md5_str,ctime)  #d0e0ca7d1f8f72d60715696d4baac3b2(key和时间戳加密后的结果)| 时间戳
print(md5_str)
respose=requests.get(url=http://127.0.0.1:8000/test.html/,headers={auth-api:auth_api_val}).text
print(respose)




#如果给Django程序发送请求头,如果headers里面的内容使用下滑杠 _,Django会不认识;
#auth-api  -----> 转换成 ‘HTTP_AUTH_API‘格式
#服务端获取clent_key=request.META.get(‘HTTP_AUTH_API‘)
View Code

服务端

技术分享技术分享
import hashlib
import time

def MD5(arg):
    hs = hashlib.md5()
    hs.update(arg.encode(utf-8))  # python3加密使用字节类型
    return hs.hexdigest()
visited_keys={} #使用memcached redis 超时时间5秒
def test(request):
    server_float_ctime=time.time()
    key=sssdkjrjefjewfakfhkj
    auth_api_val=request.META.get(HTTP_AUTH_API)  #052dd27c130f4b9b5a8a4ec4b243962d | 1507374976.4620001
    client_md5_str,client_ctime =auth_api_val.split(|,maxsplit=1)
    client_float_ctime=float(client_ctime)
    #第1关时间限制
    if client_float_ctime+5  server_float_ctime:
        return HttpResponse(想要破解密码最在5秒之内)
    #第二关 MD5加密
    server_md5_str = MD5(%s|%s % (key, client_ctime))
    if client_md5_str != server_md5_str:
        return HttpResponse(休想)
    #第三关
    if visited_keys.get(client_md5_str):
        return HttpResponse(你放弃吧)
    visited_keys[client_md5_str]=client_float_ctime
    return HttpResponse(OK)
View Code

 

漏洞:待各位看官补充。。。。

 

API验证插件

标签:upd   round   好的   获取   字节   第三关   val   ade   发送   

原文地址:http://www.cnblogs.com/bingabcd/p/7635933.html


评论


亲,登录后才可以留言!