应用场景

cmdb 这类项目的资产入库等操作,当agent 与server 端通过api 进行数据交互时,为了安全采取了两项安全措施:1、server 端需要对agent 端进行身份验证(避免有冒充agent 请况);2、当agent 采集数据提交到server 端过程需要对数据加密,数据传输到agent 端时再数据解密(防止数据传输过程被截取,泄露数据)。

api 身份认证

认证原理

server 与 agent保存相同的字符串密钥,agent 通过密钥生成签名值,把数据与签名值发送给server 端,server 根据自己的配置文件保存的密钥生成签名值与agent 端签名值比对,两者一致则认证通过否则失败。

安全加强(只针对数据传输中签名被截取安全隐患,暂不考虑server与agent 本地保存的字符串密钥安全隐患)

签名值一次性

agent 每次发送过来的签名值都会被server 记录,每次发送的签名值如果已经使用过则认证失败(防止传输中被截取后黑客可以永久使用被截取的签名密钥来认证)

动态生成签名

由于“签名值一次性”所以签名密钥必须动态生成,每次用不同的密钥。agent 每次生成签名前生成一个时间值,把时间与保存的字符串密钥组合在一起再生成一个签名值。签名值变成了动态。

签名超时设置

agent 每次发送签名与生成签名的时间到server ,server 端接收时会再本段生成一个时间,将两个时间值比较,当时间差超过10s ,则认证失败。(“签名值一次性”中对认证过的签名值记录在了字典中以{"client_time":"签名密钥"}形式存储,为了避免此字典无线增大占用内存,所以会对字典中的时间判断,超过10s 的数据进行删除,但是删除的签名数据再有相同的签名数据来认证时就不能通过“签名一次性”来排除了,所以“签名超时设置”解决了此问题)

代码

agent 端

import requests
import time
import hashlibdef gen_sign(ctime):key = "uiakjsdfasjdf898"                                 #此字符串在server端也保存一份   val = "%s|%s" %(key,ctime)                           #加入时间,动态生成签名密钥obj = hashlib.md5()                                        #生成一个对象obj.update(val.encode('utf-8'))                        #md5只能对字节形式的数据进行加密return obj.hexdigest()ctime = int(time.time()*1000)                              #*1000单位变ms,int 转化为整数(去掉小数点后的数字,而不是四舍五入)
result = requests.post(url = 'http://127.0.0.1:8000/api/test/',              #注意路径结尾一定更要以/结尾params = {'sign':gen_sign(ctime),'ctime':ctime} #相当于在url = 'http://.../?key="alskdjflskdfjkjk"',也就是在url中以get形式发送数据
)
print(result.url,result.text)#认证逻辑:agent 把签名密钥与生成签名密钥的时间一并发送到server端,server 端通过自身保存的key与agent 的时间生成签名值,两个签名比对进行认证

View Code

server 端(view.py)

import json
import hashlib                                    #此模块里有md5的类
import time
from django.shortcuts import render,HttpResponse
from django.views import View
from django.conf import settings
from rest_framework.views import APIView
from rest_framework.response import Response#生成签名的函数
def gen_sign(ctime):"""生成签名:param ctime::return:"""val = '%s|%s' %(settings.URL_AUTH_KEY,ctime,)obj = hashlib.md5()                                #实力化一个md5对象obj.update(val.encode('utf-8'))                    #md5对象只能对bytes格式数据加密return obj.hexdigest()                            #返回生成的签名值#所有的验证成功的签名密钥都会记录在SIGN_RECORD 中
SIGN_RECORD = {}class TestView(APIView):def post(self,request):print("请求来了")#由于继承了APIView所以此处的request 不是django原生的request,原生的为request._requestclient_sign = request._request.GET.get('sign')              #获取agent发来的签名密钥client_ctime = int(request._request.GET.get('ctime'))       #获取agent 发来的时间server_time = int(time.time() * 1000)                       #记录当前时间,*1000单位变成ms#认证第一关if server_time - client_ctime > 5000:                       #比对两个时间,超过5s,则认证失败return Response({'status': 'false', 'error': "路上时间太久了"})# 认证第二关if client_sign in SIGN_RECORD:                              #已经认证通过的签名会保存在SING_RECORD,新来密钥如果被认证过了就会认证失败return Response("签名已经被使用过了")#认证第三关server_sign = gen_sign(client_ctime)                        #server 端生成签名if client_sign != server_sign:                              #密钥比对来通过认证return Response({'status':'false','error':403})#认证通过进行以下操作SIGN_RECORD[client_sign] = client_ctime                     #通过认证的密钥存储起来,下次防止密钥重复使用#防止SIGN_RECORD无线增大,对于5s 之前的记录删除。对于已经认证通过并存储在该记录中的密钥,超过10s删除后,## 那么认证第二关就失效了,所以认证第一关就是为此而设for k in list(SIGN_RECORD.keys()):v = SIGN_RECORD[k]if server_time - v  > 5000:print("已经超过5s")del SIGN_RECORD[k]return Response({'status':'true','data':666})

View Code

数据加密

加密原理

通过rsa 模块生成公钥和私钥分别保存在agent 与server 端,agent 通过公钥加密数据传输到server 端通过私钥解密。rsa 加密分为1024与2048两种,生成公私钥对象时指定参数即可 pub_key_obj, priv_key_obj = rsa.newkeys(1024) ,1024指的是能加密的数据的位数,换算成字节就是1024/8=128 bytes

代码

生成公私钥,分别保存在server/agent 两端

# ######### 1. 生成公钥私钥 #########
pub_key_obj, priv_key_obj = rsa.newkeys(1024)                 # 1024/8 = 128 ,128 - 11 = 117
# 公钥字符串
pub_key_str = pub_key_obj.save_pkcs1()
pub_key_code = base64.standard_b64encode(pub_key_str)# 私钥字符串
priv_key_str = priv_key_obj.save_pkcs1()
priv_key_code = base64.standard_b64encode(priv_key_str)将生成的公私钥(经过base64.standard_b64encode处理的)分别保存在agent/server 配置文件settings.py中原生的公钥:b'-----BEGIN RSA PUBLIC KEY-----\nMIGJAoGBAJo2DEaukeIBTvc5vscIrh0gU79N+XRrf6NBGxGi6eOh7muzH3VV7UIn\nZvfUE3Nxu97DiMAC1u2JEudM8iatMChSLxSh9qFNB36ejz7dCi9DrAH6Ce46JZ7h\n+iwlo9x7Qr4uLJrQsHhia4/i89aAooNV6I8Ne+WOe3V1PvEUs+PhAgMBAAE=\n-----END RSA PUBLIC KEY-----\n'
base64.standard_b64encode编码处理后:b'LS0tLS1CRUdJTiBSU0EgUFVCTElDIEtFWS0tLS0tCk1JR0pBb0dCQUpvMkRFYXVrZUlCVHZjNXZzY0lyaDBnVTc5TitYUnJmNk5CR3hHaTZlT2g3bXV6SDNWVjdVSW4KWnZmVUUzTnh1OTdEaU1BQzF1MkpFdWRNOGlhdE1DaFNMeFNoOXFGTkIzNmVqejdkQ2k5RHJBSDZDZTQ2Slo3aAoraXdsbzl4N1FyNHVMSnJRc0hoaWE0L2k4OWFBb29OVjZJOE5lK1dPZTNWMVB2RVVzK1BoQWdNQkFBRT0KLS0tLS1FTkQgUlNBIFBVQkxJQyBLRVktLS0tLQo='

View Code

agent 端

import rsa
import base64
from config import settings
#数据加密函数
def encrypt(value_bytes):"""rsa 公钥加密:param value_bytes: 要加密的字节:return:"""key_str = base64.standard_b64decode(settings.PUB_KEY)    #settings.py 中记录了公钥pk = rsa.PublicKey.load_pkcs1(key_str)#rsa 1024 能加密的数据大小为128(1024/8)字节,rsa 本身数据占用11字节,所以对大于128字节的数据分批次加密(每次加密117(128-11)字节)最后加密的数据拼接即可。data_list = []for i in range(0,len(value_bytes),117):chunk = value_bytes[i:i+117]result = rsa.encrypt(chunk, pk)data_list.append(result)return b''.join(data_list)#进行数据加密,并且发送到agent
ctime = int(time.time()*1000)
r1 = requests.post(url=self.asset_api,params = {'sign':gen_sign(ctime),'ctime':ctime},         #传输签名密钥data=encrypt(json.dumps(info).encode('utf-8')),          #传输数据rsa 加密headers={'Content-Type':'application/json'})

View Code

server 端

#使用私钥解密的函数
import rsa
import base64
def decrypt(bytes_value):"""rsa解密:param bytes_value: 要解密的数据为bytes 类型,因为rsa 只能对bytes 类型数据加密,所以解密数据为bytes类型:return: 解密完成的字节"""key_str = base64.standard_b64decode(settings.PRIV_KEY)    #生成密钥后使用base64.standard_b64encode对公钥进行了编码处理,所以此处要用decode 解码pk = rsa.PrivateKey.load_pkcs1(key_str)                    #生成私钥证书    #rsa 1024 能加密的数据大小为128(1024/8)字节,所以需要对大于128字节的数据分批次加密(每次加密128字节)最后加密的数据拼接即可。所以解密时也是每次解密128字节,最后拼接即可result = []for i in range(0,len(bytes_value),128):chunk = bytes_value[i:i+128]                        val = rsa.decrypt(chunk, pk)                        #通过公钥证书对数据chunk 加密
        result.append(val)return b''.join(result)#利用私钥解密的函数解密数据
class AssetView(APIAuthView):def post(self, request, *args, **kwargs):body = decrypt(request._request.body)           #通过decrypt 解密数据,body 中才是原生的数据asset_info = json.loads(body.decode('utf-8'))   #解密后的数据解码再序列化加载

View Code

转载于:https://www.cnblogs.com/fanggege/p/10425528.html

API 接口认证与传输数据加密相关推荐

  1. api脑机接口-集成接口商麟游api接口认证说明

    API接⼝说明认证签名 麟游API采⽤华为云APP认证⽅式, ⽤户可以通过华为云官⽅提供的SDK发起请求. 通常, 在构建请求时, 需要使⽤有效的AppKey. AppSecret才能够⽣成认证签名. ...

  2. java实现api接口的token,基于Token的API接口认证机制

    Cookie Auth Cookie认证机制就是为一次请求认证在服务端创建一个Session对象,同时在客户端的浏览器端创建了一个Cookie对象:通过客户端带上来Cookie对象来与服务器端的ses ...

  3. 【考试记录】Apsara Clouder基础技能认证:实现调用API接口

    从今天开始,准备把阿里的认证尽可能多的考出来.原因有这么几个:研究生要毕业了,除了把论文写好,还有找工作的压力,所以想尽可能多的考出几个证来证明自己的学习能力:研究生毕业后想找个教师的工作,所以得以身 ...

  4. 微信支付、微信公众号接口认证方案

    1 微信公众号接口认证方案 1.1 认证流程 安全API接口认证方案 流程图模板_ProcessOn思维导图.流程图​www.processon.com/view/link/636e05a21e085 ...

  5. WebApi后端框架Token身份认证,Api接口Token验证

    令牌概述(Token) 在以用户账号体系作为安全认证的信息系统中,对用户身份的鉴定是非常重要的事情. 令牌机制是软件系统安全体系中非常重要的部分,在计算机身份认证中是令牌的意思,一般作为邀请.登录以及 ...

  6. 基于http协议的api接口对于客户端的身份认证方式以及安全措施[转]

    基于http协议的api接口对于客户端的身份认证方式以及安全措施 由于http是无状态的,所以正常情况下在浏览器浏览网页,服务器都是通过访问者的cookie(cookie中存储的jsessionid) ...

  7. 使用请求头认证来测试需要授权的 API 接口

    使用请求头认证来测试需要授权的 API 接口 Intro 有一些需要认证授权的接口在写测试用例的时候一般会先获取一个 token,然后再去调用接口,其实这样做的话很不灵活,一方面是存在着一定的安全性问 ...

  8. Apsara Clouder专项技能认证:实现调用API接口

    一.API 简介 1.API 的概念 API(Application Programming Interface应用程序编程接口)是一些预定义的函数,目的是提供应用程序与开发人员基于某软件或硬件得以访 ...

  9. 什么是实人认证?需要用到哪些api接口

    日常生活中,尤其是在网络上,不法分子利用盗取或者非法买卖的他人身份证件进行诈骗,比如利用他人身份信息注册社交.游戏.交易等网络平台,通过平台伺机寻找容易下手的目标,不仅给受害者带来损失,由于冒用他人身 ...

最新文章

  1. LAMP搭建UCenter
  2. 编译-speex For iOS静态库
  3. linux下通过命令来下载视频
  4. linux源码安装php缺少动态库,php源代码安装常见错误解决办法
  5. Python基础之格式化输出函数format()详解
  6. bzoj1562[NOI2009] 变换序列
  7. 【eoeAndroid社区索引】android 条形码的知识汇总
  8. 一线互联网互联网架构师自述:GitHub标星10w+,2021最新Android笔经
  9. python中如何判断词性_Python3自然语言处理——词性标注
  10. MQ入门之看MQ项目源码 XXL-MQ
  11. java kafka设置偏移量_kafka实战宝典:手动修改消费偏移量的两种方式
  12. ipad/iphone内存管理二
  13. hacker vip教程
  14. 【上海交大oj】畅畅的牙签袋(改)(枚举+模拟)
  15. SpringCloud-Gateway配置及持久化、过滤器、异常处理
  16. 像容忍自己一样容忍他人
  17. 北京大学软微第二学位可能被取消!高校第二学士学位将成历史!
  18. XBox 360 Kinect 体感游戏时代,宅男再也虐不了电脑了
  19. 学习Python开发难不难?
  20. solidworks电气元件3d库_丨部件库丨西门子3RT60交流接触器

热门文章

  1. Vue+iView table分页勾选记忆功能
  2. 自然辩证法之李约瑟难题
  3. 基于Scrapy框架的当当网编程开发图书定向爬虫
  4. hxp 36C3 CTF Web题 WriteupBin Writeup (Selenium模拟点击+Content Security Policy+Nonce+Parsley.js触发错误提示)
  5. 芋道 Spring Boot 安全框架 Spring Security 入门
  6. APP推广—区分推广渠道解决方案
  7. 计算机应用基础教材课件配图
  8. 晚上不用加班了,推荐十款精选IntelliJIdea插件,效率提升N倍
  9. 乔列斯基(Cholesky)法解方程(python,数值积分)
  10. 平方根法 乔累斯基分解Cholesky_解线性方程组的直接解法