之前需要在两台服务器之间频繁传输一些重要数据,一台服务器开放数据接口,另一台调用,为了防止数据泄露,所以简单构思了一下,在接口上添加了一个简单的token验证机制,采用时间戳、base64和密码表来完成,为对称加密。那么下面就带来python的具体实现步骤。

思路一览

采用对称加密解密,即调用数据端按照顺序生成token,服务器端按照逆顺序解析token,并从中解析出时间戳,验证时间戳有效期,有效则返回数据。

生成token

首先对一串小写大写字母及数字字符串随机打乱顺序,生成一串专属的秘钥字符串 miwen。在两台服务器都保存该段秘钥。

yuan="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
miwen="VTJBN64h1EMlwzq9ucKDxikmOtR8re3WypCS2HYZULsIg7aFPA5nb0fvjXQdoG"

然后写一个将字符串转换为base64的函数

import base64

def tob64(sstr):
    sstr=sstr.encode()
    bs4str = base64.b64encode(sstr)
    return bs4str.decode()

然后再写一个生成随机字符串的函数,用于加密扰乱

import random

def randomstr(length=5):
    pieces=[str(random.choice(yuan)) for i in range(int(length))]
    return ''.join(pieces)

接着写一个密码表加密函数,根据我们的秘钥字符串,对传入的字符串进行替换加密

def jiami(thestr):
    mistr=''
    for letter in thestr:
        if letter in yuan:
            yuan_index=yuan.index(letter)
            mi_letter=miwen[yuan_index]
            mistr=mistr+mi_letter
        else:
            mistr=mistr+letter
    return mistr

最后写一个生成token的方法,拼接时间与随机字符串,并用秘钥进行替换加密,生成一段用于传输给服务端验证的token。

import time

def geneat():
    the_time=str(int(time.time()))
    the_time=tob64(the_time)
    the_time=randomstr()+"."+the_time+"."+randomstr()
    the_time=tob64(the_time)
    at=jiami(the_time)
    return at

测试一下

验证部分

验证其实就是将传入的token逆解析,然后验证时间戳是否过期即可

def deb64(bstr):#解析base64字符串
    sstr=base64.b64decode(bstr)
    sstr=sstr.decode()
    return sstr

def jiemi(mistr):#根据秘钥替换解密回原来的字符串
    thestr=''
    for letter in mistr:
        if letter in miwen:
            mi_index=miwen.index(letter)
            the_letter=yuan[mi_index]
            thestr=thestr+the_letter
        else:
            thestr=thestr+letter
    return thestr

def returntime(at):#提取出token中时间戳的那个部分
    the_time=jiemi(at)
    the_time=deb64(the_time)
    the_time=the_time.split(".")[1]
    the_time=deb64(the_time)
    return the_time

def checkat(at):#组合上面的函数,判断时间戳是否有效,此处设置的是时间戳与服务器时间相差100秒内都有效
    try:
        the_time=returntime(at)
        if abs(int(the_time)-time.time())<100:
            return "ok"
        else:
            return "invalid"
    except:
        return "invalid"

测试一下,将上图中的那个字符串传入验证,因为已过期,所以显示失效

我们重新生成一个,然后马上再验证试下,可以看到,在有效期内,验证器返回OK

至此一个简单的token验证就完成了,在开放一些需要保密的接口时就可通过简单的token验证来保证安全了。

比如在flask上就可以这样使用

@app.route("/api/getsomething")
def getSomething():
    token=request.args.get("token")
    if checkat(token)!="ok":
        return 'access denied'
    ...
    return something

然后在调用接口的时候传入就行

import requests

def getSomething():
    token=geneat()
    params={'token':token}
    resp=requests.get('https://felixlee.cn/api/getsomething',params=params)
    return resp

其他说明

上面添加一步扰乱字符串的原因是因为,如果单单对时间戳字符串进行base64加密及密码表替换的话,很容易看出规律来的,而在生成过程中,在首尾加上随机字符串则能很好地打乱规律,更安全一些。

评论

Felix 管理员

2022第一篇文章 ( "  ̄︿ ̄)

回复

  • 最新随笔

  • 中秋经典BGM:滴滴滴
  • 猫确实喜欢在各种犄角旮旯里睡觉
  • 尝试让DALLE生成一些连续的精灵图,让gpt帮忙生成一些提示词,如果能稳定输出的话就很强大了。
    让gpt帮忙生成的DALLE提示词
    "Generate a pixel art sprite sheet of a character walking in four directions (north, south, east, west) in a retro video game style."
    "Create a series of pixel art frames showing a character performing different actions like walking, running, jumping, and attacking in a classic 2D game aesthetic."
  • 路过别人山庄的门口,被一条大黑狗边叫边追过来,幸好骑电动车,不然还不一定跑得过,哈哈哈哈哈哈哈哈哈哈。
  • 最近两周也没咋出去玩,主要也是觉得没啥好玩的(笑哭)。看完布莱恩阿瑟的《复杂经济学》后,里面那个酒吧问题勾起我的兴趣,最近空了就花了些时间实现个python版本,顺便搞了篇博文,很享受这种新知识能和已有知识碰撞的感觉。(配张前段时间拍的图片,梧桐山门口前面那条路,挺漂亮的)
  • 盐田港夜景
  • 为啥这猫总喜欢喝杯子里的水
  • 确实开始冷了,在树林里至少要比人类聚集区低个几度,进出入口就能很明显感觉到。看看深圳水库的风景,貌似后面的视野更开阔。