API验证及AES加密
API验证
API验证:
a. 发令牌: 静态
PS: 隐患 key被别人获取
b. 动态令牌
PS: (问题越严重)用户生成的每个令牌被黑客获取到,都会破解
c. 高级版本
PS: 黑客网速快,会窃取, so要对数据加密
d. 终极版本 特点:
为什么要用API ?
- 数据在传输过程中,保证数据安全
你是如何设计的 ?
- Tornado 中的加密Cookie类似
- 创建动态key md5(key + time)|time (Tornado中也是这么做)
- 限制
- 第一关: 时间
- 第二关: 算法规则
- 第三关: 已访问的记录
PS: 黑客网速快,会窃取, so要对数据加密
a. 客户端和服务端都有一个相同的key
客户端把key发给服务端,服务端拿着自己的key和客户端的key做比较 ###客户端 import time
import requests key = "asdfasdfasdfasdf098712sdfs" response = requests.get("http://127.0.0.1:8000/api/asset.html",headers={'OpenKey':key})
print(response.text) ###服务端 #print(request.META)
key = request.META.get("HTTP_OPENKEY")
if key != settings.AUTH_KEY:
return HttpResponse("验证失败")
b. key和时间
#客户端和服务端都有一个相同的key
#客户端把加密key和当前时间发给服务端,服务端收到后把客户端发来的时间和自己的key加密
#然后把加密后的字串和客户端的字串比较 #客户端 import time
import requests
import hashlib ctime = time.time()
key = "asdfasdfasdfasdf098712sdfs"
new_key = "%s|%s" %(key,ctime,) m = hashlib.md5()
m.update(bytes(new_key,encoding='utf-8')) #里面是字节数据
md5_key = m.hexdigest() #返回值是字符窜类型 md5_time_key = "%s|%s" %(md5_key,ctime) response = requests.get("http://127.0.0.1:8000/api/asset.html",headers={'OpenKey':md5_time_key})
print(response.text) #服务端
client_md5_time_key = request.META.get("HTTP_OPENKEY") client_md5_key,client_ctime = client_md5_time_key.split("|") temp = "%s|%s"%(settings.AUTH_KEY,client_ctime)
m = hashlib.md5()
m.update(bytes(temp, encoding='utf-8'))
server_md5_key = m.hexdigest() if server_md5_key != client_md5_key:
return HttpResponse("验证失败")
c. 高级版本
#客户端和服务端都有一个相同的key
#客户端把加密key和当前时间发给服务端
#服务端验证:
#1)服务端判断服务器当前的时间是否比客户端时间快10s,如果在10s内通过,有效的杜绝了案例二成千上万的key
#2)服务器获取客户端时间和自己key加密然后和 客户端获取到的key比较
#3)删除与现在时间相差10s的数据(之后用memcache,redis)
#3)在字典里判断是否有这个key,如果有不通过,没有加入字典(之后用memcache,redis) #客户端
import time
import requests
import hashlib ctime = time.time()
key = "asdfasdfasdfasdf098712sdfs"
new_key = "%s|%s" %(key,ctime,) m = hashlib.md5()
m.update(bytes(new_key,encoding='utf-8')) #里面是字节数据
md5_key = m.hexdigest() #返回值是字符窜类型 md5_time_key = "%s|%s" %(md5_key,ctime) print(md5_time_key)
response = requests.get("http://127.0.0.1:8000/api/asset.html",headers={'OpenKey':md5_time_key}) #黑客获取调用
#response = requests.get("http://127.0.0.1:8000/api/asset.html",headers={'OpenKey':"f610077a7001c53b5a74868c5544b388|1501514254.455578"})
print(response.text) #服务端
api_key_record ={
"76942d662d98ebe3b920a7b791bf5040|1501510243.92804":1501510243.92804,
} def asset(request): client_md5_time_key = request.META.get("HTTP_OPENKEY") client_md5_key,client_ctime = client_md5_time_key.split("|")
client_ctime = float(client_ctime)
server_ctime = time.time() #第一关 时间关
if server_ctime - client_ctime > 10:
return HttpResponse("第一关 小伙子,别虎我,太长了") #第二关 客户端时间和服务端key加密和 客户端的密钥对比
temp = "%s|%s"%(settings.AUTH_KEY,client_ctime)
m = hashlib.md5()
m.update(bytes(temp, encoding='utf-8'))
server_md5_key = m.hexdigest()
if server_md5_key != client_md5_key:
return HttpResponse("第二关 规则正确") #以后基于memcache,目前先写入内存删除超过10s的值
for k in list(api_key_record.keys()):
v = api_key_record[k]
if server_ctime > v:
del api_key_record[k] #第三关 判断字典里是否有之前访问的key,如果有不通过,没有加入字典
if client_md5_time_key in api_key_record:
return HttpResponse("第三关 已经有人来过了")
else:
api_key_record[client_md5_time_key] = client_ctime + 10
d. 终极版本
注意: key 是从配置文件获取的 装饰器要返回Httpresponse对象
__author__ = 'Administrator'
from Crypto.Cipher import AES
from lib.conf.config import settings
def encrypt(message):
"""
数据加密
:param message:
:return:
"""
key = settings.DATA_KEY
cipher = AES.new(key, AES.MODE_CBC, key)
ba_data = bytearray(message,encoding='utf-8')
v1 = len(ba_data)
v2 = v1 % 16
if v2 == 0:
v3 = 16
else:
v3 = 16 - v2
for i in range(v3):
ba_data.append(v3)
final_data = ba_data.decode('utf-8')
msg = cipher.encrypt(final_data) # 要加密的字符串,必须是16个字节或16个字节的倍数
return msg def decrypt(msg):
"""
数据解密
:param message:
:return:
"""
from Crypto.Cipher import AES
key = settings.DATA_KEY
cipher = AES.new(key, AES.MODE_CBC, key)
result = cipher.decrypt(msg) # result = b'\xe8\xa6\x81\xe5\x8a\xa0\xe5\xaf\x86\xe5\x8a\xa0\xe5\xaf\x86\xe5\x8a\xa0sdfsd\t\t\t\t\t\t\t\t\t'
data = result[0:-result[-1]]
return str(data,encoding='utf-8') def auth():
"""
API验证
:return:
"""
import time
import requests
import hashlib ctime = time.time()
key = "asdfasdfasdfasdf098712sdfs"
new_key = "%s|%s" %(key,ctime,) m = hashlib.md5()
m.update(bytes(new_key,encoding='utf-8')) #里面是字节数据
md5_key = m.hexdigest() #返回值是字符窜类型 md5_time_key = "%s|%s" %(md5_key,ctime) return md5_time_key
客户端lib/utils
from Crypto.Cipher import AES
import requests
import json
from lib.utils import encrypt
from lib.utils import auth #对数据加密字典
v1 = encrypt(json.dumps({"k1":"v1"})) #获取的是加密后的字节
print(v1) response = requests.post(
url="http://127.0.0.1:8000/api/asset.html",
headers={'OpenKey':auth(),'content-type':'application/json'},
data=v1
) print(response.text)
客户端调用
import json
import hashlib
from django.shortcuts import render,HttpResponse
from repository import models
from django.conf import settings
from api.service import PluginManager
import time
import json
from Crypto.Cipher import AES api_key_record ={
"76942d662d98ebe3b920a7b791bf5040|1501510243.92804":1501510243.92804,
} def decrypt(msg):
key = b'dfdsdfsasdfdsdfs'
cipher = AES.new(key, AES.MODE_CBC, key)
result = cipher.decrypt(msg) # 把加密后的字节解密成不加密的字节
data = result[0:-result[-1]]
return str(data, encoding='utf-8') def outer(func):
def wrapper(request):
client_md5_time_key = request.META.get("HTTP_OPENKEY") client_md5_key, client_ctime = client_md5_time_key.split("|")
client_ctime = float(client_ctime)
server_ctime = time.time() # 第一关 时间关
if server_ctime - client_ctime > 30:
return HttpResponse("第一关 小伙子,别虎我,太长了") # 第二关 客户端时间和服务端key加密和 客户端的密钥对比
temp = "%s|%s" % (settings.AUTH_KEY, client_ctime)
m = hashlib.md5()
m.update(bytes(temp, encoding='utf-8'))
server_md5_key = m.hexdigest()
if server_md5_key != client_md5_key:
return HttpResponse("第二关 规则正确") # 以后基于memcache,目前先写入内存删除超过10s的值
for k in list(api_key_record.keys()):
v = api_key_record[k]
if server_ctime > v:
del api_key_record[k] # 第三关 判断字典里是否有之前访问的key,如果有不通过,没有加入字典
if client_md5_time_key in api_key_record:
return HttpResponse("第三关 已经有人来过了")
else:
api_key_record[client_md5_time_key] = client_ctime + 10
obj = func(request)
return obj return wrapper @outer
def asset(request): if request.method == 'GET':
ys = '重要的不能被闲杂人等看的数据'
return HttpResponse(ys) elif request.method == 'POST': server_info = decrypt(request.body)
server_info = json.loads(server_info) # # 新资产信息
# server_info = json.loads(request.body.decode('utf-8'))
hostname = server_info['basic']['data']['hostname']
# 老资产信息
server_obj = models.Server.objects.filter(hostname=hostname).first()
if not server_obj:
return HttpResponse('当前主机名在资产中未录入') PluginManager(server_info,server_obj,hostname).exec_plugin() return HttpResponse("...")
服务端调用
API验证及AES加密的更多相关文章
- 前后端API交互数据加密——AES与RSA混合加密完整实例
前言 前段时间看到一篇文章讲如何保证API调用时数据的安全性(传送门:https://blog.csdn.net/ityouknow/article/details/80603617),文中讲到利用R ...
- CMDB 数据加密 最终整合API验证+AES数据加密
当CMDB运行在内网的时候,经过API验证的三关是没有问题的,但是如果运行在外网,有一个问题是,黑客截取后的访问速度比客户端快的时候还会造成数据泄露.为了解决这个问题,就要对数据进行加密 RSA加密 ...
- 你真的了解字典(Dictionary)吗? C# Memory Cache 踩坑记录 .net 泛型 结构化CSS设计思维 WinForm POST上传与后台接收 高效实用的.NET开源项目 .net 笔试面试总结(3) .net 笔试面试总结(2) 依赖注入 C# RSA 加密 C#与Java AES 加密解密
你真的了解字典(Dictionary)吗? 从一道亲身经历的面试题说起 半年前,我参加我现在所在公司的面试,面试官给了一道题,说有一个Y形的链表,知道起始节点,找出交叉节点.为了便于描述,我把上面 ...
- API验证
API验证说明 API验证: a. 发令牌: 静态 PS: 隐患 key被别人获取 b. 动态令牌 PS: (问题越严重)用户生成的每个令牌被黑客获取到,都会破解 c. 高级版本 PS: 黑客网速快, ...
- c#和js互通的AES加密解密
一.使用场景 在使用前后端分离的框架中常常会进行传输数据相互加密解密以确保数据的安全性,如web Api返回加密数据客户端或web端进行解密,或者客户端或web端进行加密提交数据服务端解密数据等等. ...
- Java aes加密C#解密的取巧方法
摘要: 项目开发过程中遇到一个棘手的问题:A系统使用java开发,通过AES加密数据,B系统使用C#开发,需要从A系统获取数据,但在AES解密的时候遇到麻烦.Java的代码和C#的代码无法互通. Ja ...
- android base64 和 aes 加密 解密
package pioneerbarcode.ccw.com.encryptanddecode;import android.os.Bundle;import android.support.v7.a ...
- RAS RC4 AES 加密 MD5
这两者唯一的相同点是设计者中都包含了MIT的Ron Revist教授.RSA是公钥密码算法,优点:不用事先通过秘密信道传递密钥,可以用于数字签名.缺点:速度慢RC4是序列密码算法,优点:速度快,缺点: ...
- Node 实现 AES 加密,结果输出为“byte”。
Node 实现 AES 加密,结果输出为"byte". 最近做个需求,对接一个平台的接口,该平台采用 AES (Advanced Encryption Standard)加密算法, ...
随机推荐
- JS基础三
1.delete删除对对象的属性和方法的定义.强制解除对它的引用,将其设置为 undefined delete 运算符不能删除开发者未定义的属性和方法. 2.void 运算符对任何值返回 undefi ...
- node命令curl
一.打开另一个命令行窗口,运行下面的命令. curl -X POST --data "name=Jack" 127.0.0.1:3000 上面代码使用 POST 方法向服务器发送一 ...
- window7 安装sass和compass
官网有详细的介绍,但是安装时候还是出现了一些小问题. 首先下载Rudy,然后根据提示勾选加入环境变量,由于第一次使用,我就选择了" msys2 base installlation" ...
- 大数据 --> ProtoBuf的使用和原理
ProtoBuf的使用和原理 一.简介 Protobuf是一个灵活的.高效的用于序列化数据的协议.相比较XML和JSON格式,protobuf更小.更快.更便捷.Protobuf是跨语言的,并且自带了 ...
- [bzoj1565][NOI2009]植物大战僵尸_网络流_拓扑排序
植物大战僵尸 bzoj1565 题目大意:给你一张网格图,上面种着一些植物.你从网格的最右侧开始进攻.每个植物可以对僵尸提供能量或者消耗僵尸的能量.每个植物可以保护一个特定网格内的植物,如果一个植物被 ...
- [bzoj1026][SCOI2009]windy数_数位dp
windy数 bzoj-1026 题目大意:求一段区间中的windy数个数. 注释:如果一个数任意相邻两位的差的绝对值都不小于2,这个数就是windy数,没有前导0.$区间边界<=2\cdot ...
- 为什么说android UI操作不是线程安全的
转载于:http://blog.csdn.net/lvxiangan/article/details/17218409#t2 UI线程及Android的单线程模型原则 使用Worker线程 Commu ...
- js网页判断移动终端浏览器版本信息是安卓还是苹果ios,判断在微信浏览器跳转不同页面,生成二维码
一个二维码,扫描进入网页,自动识别下载苹果和安卓客户端,判断网页如下,(只有苹果的微信不能自动跳转)所以加个微信判断. <!DOCTYPE html> <html> <h ...
- php缩放gif和png图透明背景变成黑色的解决方法_php技巧
工作中需要缩放一些gif图然后在去Imagecopymerge,可是发现使用了imagecreatetruecolor和imagecopyresampled后发现背景图不对,本来透明的背景图变成了黑色 ...
- drbd(四):drbd多节点(drbd9)
1.drbd多节点简介 在drbd9以前,drbd一直只能配置两个节点,要么是primary/secondary,要么是primary/primary.虽然在这些版本上也能配置第三个节点实现三路节点的 ...