CMDB之http验证

web应用主要面临的安全问题:
1.数据篡改
2.数据窃取
3.重放攻击
4.非法参数提交 (SQL注入,XSS等)

HTTP验证的原理

key
这个key只能是客户端和服务端知道,否则无法保证请求的合法性验证了。key的生成方式可以根据应用来区分:

传统web应用:服务器可以根据客户端浏览器的信息,结合请求的IP,User-Agent等信息产生一个key。

移动APP应用:可以通过事先约定key的方式(前提不能被反编译),或者通过一些非对称加密来生成一个key

时间戳
服务端和客户端约定一个请求时间范围,超过这个时间段就是非法请求

资产入库时,为了防止他人发送恶意请求,篡改数据,所以我们需要对请求进行http验证
客户端和服务端都保存随机字符串
服务端

import time
from django.shortcuts import render,HttpResponse
from repository import models
from django.conf import settings
# redis/Memcache
api_key_record = {
    # "1b96b89695f52ec9de8292a5a7945e38|1501472467.4977243":1501472477.4977243
}
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_time = time.time()

    # 第一关
    if server_time-client_ctime > 10:
        return HttpResponse('【第一关】小伙子,别唬我,太长了')
    # 第二关
    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('【第二关】小子,你是不是修改时间了')

    for k in list(api_key_record.keys()):
        v = api_key_record[k]
        if server_time > v:
            del api_key_record[k]

    # 第三关:
    if client_md5_time_key in api_key_record:
        return HttpResponse('【第三关】有人已经来过了...')
    else:
        api_key_record[client_md5_time_key] = client_ctime + 10
        return HttpResponse('成功')


    if server_md5_key != client_md5_key:
        return HttpResponse('认证失败...')

客户端

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})
print(response.text)

模拟黑客攻击

# 截取随机字符串,放在请求头中
import requests
response = requests.get(
    url='http://127.0.0.1:8000/api/asset.html',
    headers={"OpenKey":"0895c7e295202eda30678e687cc2c817|1501546586.34368"})
print(response.text)

python AES加密

高级加密标准(Advanced Encryption Standard,AES),在密码学中又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准。这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用。经过五年的甄选流程,高级加密标准由美国国家标准与技术研究院(NIST)于2001年11月26日发布于FIPS PUB 197,并在2002年5月26日成为有效的标准。2006年,高级加密标准已然成为对称密钥加密中最流行的算法之一。
AES只是个基本算法,实现AES有若干模式。其中的CBC模式因为其安全性而被TLS(就是https的加密标准)和IPSec(win采用的)作为技术标准。简单地说,CBC使用密码和salt
(起扰乱作用)按固定算法(md5)产生key和iv。然后用key和iv(初始向量,加密第一块
明文)加密(明文)和解密(密文)。
下面介绍python实现的AES加密解密实例,这里采用CBC模式,用到了pycrypto‎模块
加密

"""
安装模块pycrypto
pip3 install pyCrypto
"""

from Crypto.Cipher import AES


def encrypt(message):
    """
    AES加密发送字符串
    :param message: (str)传入明文字符串
    :return: 密文
    """
    # 注意此时的key只能是16个字节
    key = b'dfdsdfsasdfdsdfs'
    # chuan
    cipher = AES.new(key, AES.MODE_CBC, key)
    # 要加密的字符串,必须是16个字节或16个字节的倍数
    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)
    return msg

# ############################## 解密 ##############################
def decrypt(msg):
    """
    AES解密
    :param msg: 密文
    :return:  解密后的字符串
    """
    # 注意此时的key只能是16个字节
    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')


raw = "昌平刘德华"
code_raw = encrypt(raw)
print(raw)              # 原数据
print(code_raw)         # 加密后的字节
decode_raw = decrypt(code_raw)
print(decode_raw)      # 解密后的字符串

原文地址:https://www.cnblogs.com/zouruncheng/p/7270501.html