zoukankan      html  css  js  c++  java
  • 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)      # 解密后的字符串
    
    
  • 相关阅读:
    Js/Jquery获取iframe中的元素
    js常用技巧汇总
    jquery常用技巧
    Tomcat远程调试
    常用SQL
    CRM-stark组件
    面试题-linux基础
    vue2-通过axios实现数据请求
    Vue01
    面试题之python基础
  • 原文地址:https://www.cnblogs.com/zouruncheng/p/7270501.html
Copyright © 2011-2022 走看看