突然发现好久没有更新了,主要是前段时间忙双十一太忙了,通宵压测几乎15次,可以说从国庆放假回来不是在压测就是在补觉,然后公司的夜宵吃几次也就腻了,所以全链路压测的新鲜感一消失就会很迷茫。不过每次看到那些大佬们也都熬夜压测,心里还多少平衡一点…
正文
在公司的一部分产品的API中,有接口是使用AES对称加解密方法来实现,并且采用ECB模式,是链接内部工具的,但是这个API的demo是用python2来写的,由于我的Django是python3.8,于是就要自己手改。代码如下,这里没有加上加解密的部分。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#引入依赖包
import time
import base64
from Crypto.Cipher import AES
appname = "这里是应用名称"
timestamp = int(time.time() * 1000)
print("当前时间戳是:" + str(timestamp))
#封装AECS
class prpcrypt():
def __init__(self, key):
self.key = key
self.mode = AES.MODE_ECB
self.BS = len(key)
# 如果刚好是s是BS的倍数,那么补一组
self.pad = lambda s: s + (self.BS - len(s) % self.BS) * chr(self.BS - len(s) % self.BS).encode()
# python3这里多了一个encode,python2的写法是self.pad = lambda s: s + (self.BS - len(s) % self.BS) * chr(self.BS - len(s) % self.BS)
self.unpad = lambda s: s[0:-s[-1]] # python2的写法是:self.unpad = lambda s : s[0:-ord(s[-1])],这里把ord去掉了
# 加密
def Encrypt(self,text):
text = self.pad(text)
cryptor = AES.new(self.key,self.mode, b'0000000000000000') #必须16位
ciphertext = cryptor.encrypt(text)
return ciphertext
#签名计算
def sign(timestamp):
content = format("appName=%s;timestamp=%s" % (appname, timestamp))
print("传入的动态值:", content)
key = base64.decodebytes(b'1234567890abcdefghijkl==') # 这里是secret,我这里是24位
ciphertext = prpcrypt(key).Encrypt(content.encode('utf-8')) # utf8编码
endata = base64.urlsafe_b64encode(ciphertext).decode().rstrip('=') # 必须urlsafe格式后,tstrip掉"=",这里python3,需要添加一个decode(),这样就可以由bytes转str了
print('加密签名是:',endata)
return endata
pass
if __name__ == '__main__':
signature = sign(timestamp) # 这里通过时间戳的变化和不同的appname,来得到加密签名
其实这比较恶心的地方就是Python3.x和Python2.x在一些类型上不同,比如长类型和bytes的用法上,总结一下,Python3.x和Python2.x在套接字返回值解码上有区别:
python bytes和str两种类型可以通过函数encode()
和decode()
相互转换,str→bytes
:encode()
方法。str
通过encode()
方法可以转换为bytes
。bytes→str
:decode()
方法。如果我们从网络或磁盘上读取了字节流,那么读到的数据就是bytes
。要把bytes
变为str
,就需要用decode()
方法。
hex加密的python2->3
python2的脚本是这样的:
1
2
3
4
5
6
7
8
9#根据你申请的账号和对应的key,加上当前的时间戳,得到一个秘钥
import md5
account="test-skyline";
key = "myPrivateKey";
timeStamp = 1531310369L;
toEncrypt = account+key+str(timeStamp);
signature=md5.new(toEncrypt).digest().encode('hex')
# 结果: ('5fbd62ee4cf62c503ec8e417d7289816', <type 'str'>)
而python3的版本就是这样了:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15# 原脚本是python2的,现在要转成python3版本,https://yuque.antfin-inc.com/at7ocb/qbn0oy/cahbgn
from hashlib import md5
import binascii
account = "test-skyline"
key = "myPrivateKey"
timeStamp = 1531310369 # python3直接这么写就行,不用带L
en_data = account+key+str(timeStamp)
toEncrypt = md5(en_data.encode("utf-8")) # python3的写法
signature = binascii.b2a_hex(toEncrypt.digest())
print(signature,type(signature))
# 结果:b'5fbd62ee4cf62c503ec8e417d7289816' <class 'bytes'>