之前需要在两台服务器之间频繁传输一些重要数据,一台服务器开放数据接口,另一台调用,为了防止数据泄露,所以简单构思了一下,在接口上添加了一个简单的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 滴滴滴
  • 时不时感觉自己的思维有点像闲聊,下一个话题总是跟上一句话有点关系,或为直接关系,或者因其陷入的沉思从而引发的发散思维进而改变的话题,层层递进。除去位于context中的思考,其他就是因为各种感受(视觉、听觉)的刺激,如看到什么、听到什么而引发的思考,然后又进入context的循环。比如有时能因为一段文字或者一段对话放大到某种强烈的情绪。因为频繁观察到这种情况,故记录下。
  • 才发现百度在搜索场景开始接入ai问答了,和文心一言貌似是分离开的产品,而且回答和new bing类似有引用的格式,之前的文心一言并没有。可能这个是To C的,文心一言是To B的吧。
  • (°ー°〃) (°ー°〃) 看你睡得那么香就不赶你了,整个抬走,换把椅子ㄟ(▔ ,▔)ㄏ
  • 还有这个移动端之前的随笔显示效果图片做对比,现在这样就更方便阅读一些
  • 找了点时间,重新调整了一下随笔的页面,这样看就顺眼多了,附上一张以前的随笔页图片。
  • 对于自己暂时没有能力改变的事情,屏蔽相关信息是保持平常心的方法之一,毕竟人的精力和注意力是有限的,投入眼前的事情反倒能在这个浮躁的世界收获一些自己的东西。专注脚下,偶尔抬头。
  • 这个随笔的页面找时间得改一改,阅读体验不太好......