之前需要在两台服务器之间频繁传输一些重要数据,一台服务器开放数据接口,另一台调用,为了防止数据泄露,所以简单构思了一下,在接口上添加了一个简单的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第一篇文章 ( "  ̄︿ ̄)

回复

  • 最新随笔

  • (°ー°〃) (°ー°〃) 看你睡得那么香就不赶你了,整个抬走,换把椅子ㄟ(▔ ,▔)ㄏ
  • 还有这个移动端之前的随笔显示效果图片做对比,现在这样就更方便阅读一些
  • 找了点时间,重新调整了一下随笔的页面,这样看就顺眼多了,附上一张以前的随笔页图片。
  • 对于自己暂时没有能力改变的事情,屏蔽相关信息是保持平常心的方法之一,毕竟人的精力和注意力是有限的,投入眼前的事情反倒能在这个浮躁的世界收获一些自己的东西。专注脚下,偶尔抬头。
  • 这个随笔的页面找时间得改一改,阅读体验不太好......
  • 对于一些娱乐片段或者碎片化阅读的记忆,别穷思竭虑般地唤起回忆,想变得清晰,不能马上想起就放弃。毕竟在信息时代每天接受的信息量级巨大,若想大脑都填满这些碎片化的信息也是天方夜谭,而且在无法想起时也不建议有苦恼的情绪(如:我是不是有健忘症?是不是越来越严重了?之类的),因为频繁给自己这类心理暗示真的很有可能会往相关趋势发展。另外对于一些系统性学习的知识也建议保持类似的态度,因为除了一些频繁使用的知识,人脑真的记忆不过来那么多东西,在想不起时依靠记忆中相关的知识索引在世界中找到对应的内容即可。
  • 发现一个有趣现象,看了看发的文章,我用“我们”比用“我”更频繁,这是为啥。(随便一提,这是2022年第一条随笔,(笑哭))
  • 对我来说,写东西很好的一点是,自己写的东西,后面基本都会再看,一遍或者很多遍。这样就可以很好地发现自己之前的漏洞,并看看现在有什么变化。