介绍
在接口测试中我们常常遇到各种需要加密的场景,不同的加密方式需要我们使用不同的算法去实现
针对网络数据安全问题,可以用以下几种数据加密方式来解决:
数据加密方式 | 描述 | 主要解决的问题 | 常用算法 |
---|---|---|---|
对称加密 | 指数据加密和解密使用相同的密钥 | 数据的机密性 | DES, AES |
非对称加密 | 也叫公钥加密,指数据加密和解密使用不同的密钥–密钥对儿 | 身份验证 | DSA,RSA |
单向加密 | 指只能加密数据,而不能解密数据 | 数据的完整性 | MD5,SHA系列算法 |
编码与解码
通常所说的加密方式,都是对二进制编码的格式进行加密的,对应到Python中,则是我们的Bytes。所以当我们在Python中进行加密操作的时候,要确保我们操作的是Bytes,否则就会报错。将字符串和Bytes互相转换可以使用encode()和decode()方法。
encode()
:str对象的方法,用于将字符串转换为二进制数据(即bytes),也称为“编码”。decode()
:bytes对象的方法,用于将二进制数据转换为字符串,也称为“解码”。- 在设置解码采用的字符编码时,需要与编码时采用的字符编码一致。使用decode()方法时,同样不会修改原字符串。
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2022/6/15 20:02
# @Author : shisuiyi
# @File : str_to_Bytes.py
# @Software: win10 Tensorflow1.13.1 python3.9
# encode()编码
str0 = '不予の测试笔记'
byte0 = str0.encode("GBK")
print("编码前:", str0)
print("编码后:", byte0)
byte1 = b'\xb2\xbb\xd3\xe8\xa4\xce\xb2\xe2\xca\xd4\xb1\xca\xbc\xc7'
str1 = byte1.decode("GBk")
print("解码后:", str1)
输出:
编码前: 不予の测试笔记
编码后: b'\xb2\xbb\xd3\xe8\xa4\xce\xb2\xe2\xca\xd4\xb1\xca\xbc\xc7'
解码后: 不予の测试笔记
Base64加密与解密
# -*- coding: utf-8 -*-
import base64
def bs64_data_encode(st): # base64加密
new_str = str(st)
encode_str = base64.b64encode(new_str.encode())
return encode_str
def bs64_data_decode(st): # base64解密
res = base64.b64decode(st).decode()
return res
if __name__ == '__main__':
print(bs64_data_encode('不予の测试笔记'))
print(bs64_data_decode('5LiN5LqI44Gu5rWL6K+V56yU6K6w'))
输出结果:
b'5LiN5LqI44Gu5rWL6K+V56yU6K6w'
不予の测试笔记
MD5加密
- 简介
MD5加密即message-digest algorithm 5(信息-摘要算法),即信息-摘要算法,可以将一个字符串,或文件,或压缩包,执行md5后,就可以生成一个固定长度为128bit的串。
- 用途
加密注册用户的密码。
网站用户上传图片 / 文件后,将MD5值作为文件名。(MD5可以保证唯一性)
key-value数据库中使用MD5值作为key。
比较两个文件是否相同。(在下载资源的时候,发现网站提供了MD5值,就是用来检测文件是否被篡改)
- 使用hashlib模块进行md5操作
# -*- coding: utf-8 -*-
import hashlib # 导入导入模块hashlib
def MD5_demo(str):
md = hashlib.md5() # 创建md5对象
md.update(str.encode(encoding='utf-8'))
return md.hexdigest() # 小写
if __name__ == "__main__":
# 待加密信息
str0 = '不予の测试笔记'
md5_str = MD5_demo(str0)
print('加密前为 :' + str0)
print('加密后为 :' + md5_str)
输出结果:
加密前为 :不予の测试笔记
加密后为 :a6ac80c8865b983a163ea03ed24a2d8b
sha1加密
SHA1的全称是Secure Hash Algorithm(安全哈希算法) 。SHA1基于MD5,加密后的数据长度更长,它对长度小于264的输入,产生长度为160bit的散列值。比MD5多32位,因此,比MD5更加安全,但SHA1的运算速度就比MD5要慢。
# -*- coding: utf-8 -*-
"""
使用sha1加密算法,返回str加密后的字符串
"""
import hashlib
def sha1_secret_str(s: str):
sha = hashlib.sha1(s.encode('utf-8'))
encrypts = sha.hexdigest()
return encrypts
if __name__ == '__main__':
s = "不予の测试笔记"
sha1_str = sha1_secret_str(s)
print('加密前为 :' + s)
print('加密后为 :' + sha1_str)
输出结果:
加密前为 :不予の测试笔记
加密后为 :796f1c0154647422ffc2ca9eb62041e9376c66af
SHA256
比特币挖矿的御用算法
SHA256是SHA-2下细分出的一种算法
SHA-2,名称来自于安全散列算法2(英语:Secure Hash Algorithm 2)的缩写,一种密码散列函数算法标准(哈希算法),由美国国家安全局研发,属于SHA算法之一,是SHA-1的后继者。
SHA-2下又可再分为六个不同的算法标准,包括了:SHA-224、SHA-256、SHA-384、SHA-512、SHA-512/224、SHA-512/256。这些变体除了生成摘要的长度 、循环运行的次数等一些微小差异外,
算法的基本结构是一致的。对于任意长度的消息,SHA256都会产生一个256bit长的哈希值,称作消息摘要。这个摘要相当于是个长度为32个字节的数组,通常用一个长度为64的十六进制字符串来表示。
# -*- coding: utf-8 -*-
import hashlib
def sha256_single(value):
"""
sha256加密
:param value: 加密字符串
:return: 加密结果转换为16进制字符串,并大写
"""
hsobj = hashlib.sha256()
hsobj.update(value.encode("utf-8"))
return hsobj.hexdigest().upper()
if __name__ == '__main__':
s = "不予の测试笔记"
sha256_str = sha256_single(s)
print('加密前为 :' + s)
print('加密后为 :' + sha256_str)
输出结果:
加密前为 :不予の测试笔记
加密后为 :F218FC60E61A5F910442686A6882B608AC5A81F9D021A4FCF271E2BE8252DE45
DES加密
安装和导入:
安装:pip install pyDes
导入:from pyDes import des, CBC, PAD_PKCS5
示例:
# -*- coding: utf-8 -*-
"""
@FileName: des.py
@Author: shisuiyi
@time: 2022/06/16
"""
from pyDes import des, CBC, PAD_PKCS5
import binascii
"""
DES加密、解密
"""
class DesHandle:
def __init__(self, text):
self.text = text
self.KEY = '12345678' # 这个key是固定问开发,
def des_encrypt(self):
"""
DES 加密
:param s: 原始字符串
:return: 加密后字符串,16进制
"""
secret_key = self.KEY # 密码
iv = secret_key # 偏移
# secret_key:加密密钥,CBC:加密模式,iv:偏移, padmode:填充
des_obj = des(secret_key, CBC, iv, pad=None, padmode=PAD_PKCS5)
# 返回为字节
secret_bytes = des_obj.encrypt(self.text.encode("utf-8"), padmode=PAD_PKCS5)
# 返回为16进制
return binascii.b2a_hex(secret_bytes)
def des_descrypt(self):
"""
DES 解密
:param s: 加密后的字符串,16进制
:return: 解密后的字符串
"""
secret_key = self.KEY
iv = secret_key
des_obj = des(secret_key, CBC, iv, pad=None, padmode=PAD_PKCS5)
decrypt_str = des_obj.decrypt(binascii.a2b_hex(self.text), padmode=PAD_PKCS5)
return bytes.decode(decrypt_str) # bytes.decode() 将bit转为str
if __name__ == '__main__':
handle1 = DesHandle("不予の测试笔记")
print(handle1.des_encrypt())
handle2 = DesHandle("d902f013c0d73869401b7b7e7fa694a84de91ae7c5fbeffd")
print(handle2.des_descrypt())
输出结果:
b'd902f013c0d73869401b7b7e7fa694a84de91ae7c5fbeffd'
不予の测试笔记
AES加密
AES算法详解:高级加密标准,它是一种对称加密算法,AES只有一个密钥,这个密钥既用来加密,也用于解密。
AES加密方式有五种:ECB, CBC, CTR, CFB, OFB。
从安全性角度推荐CBC加密方法,本文介绍了CBC,ECB两种加密方法的python实现。
CBC 和ECB模式的区别就是:
CBC加密需要一个十六位的key(密钥)和一个十六位iv(偏移量)
ECB加密不需要iv,只需要key(密钥)
安装
在 Windows下使用AES时要安装的是pycryptodome 模块
pip install pycryptodome
在 Linux下使用AES时要安装的是pycrypto模块
pip install pycrypto
AES的ECB 模式实现
# -*- coding: utf-8 -*-
import base64
from Crypto.Cipher import AES
AES_KEY = 'aw123zsc212s9ju0' # It must be 16, 24 or 32 bytes long (respectively for *AES-128*, *AES-192* or *AES-256*).
def add_to_16(text: str) -> bytes:
"""
不足16位的地方补全位数
:param text: 源字符串
:return: 补足字符串
"""
b_text = text.encode('utf-8')
# 计算需要补的为位数
if len(text) % 16:
add = 16 - (len(b_text) % 16)
else:
add = 0
return b_text + (b'\0' * add)
def encrypt_by_aes(text: str, key: str) -> str:
"""
加密函数
:param text: 源字符串
:param key: 密钥
:return: 加密字符串
"""
key = key.encode('utf-8')
text = add_to_16(text) # 如果长度不够补足 16 位
cryptos = AES.new(key, AES.MODE_ECB) # 使用ECB模式
cipher_text = cryptos.encrypt(text) # 加密
return base64.standard_b64encode(cipher_text).decode('utf-8') # 将加密结果转为base64编码输出
def decrypt_by_aes(text: str, key: str):
"""
解密函数
:param text: 加密字符串
:param key: 密钥
:return: 解密结果
"""
key = key.encode('utf-8')
text = text.encode('utf-8')
text = base64.b64decode(text) # 先使用base64解码
cryptos = AES.new(key, AES.MODE_ECB)
cipher_text = cryptos.decrypt(text) # 解密
return cipher_text.decode('utf-8').strip('\0')
if __name__ == '__main__':
source_str = '不予の测试笔记'
encrypt_str = encrypt_by_aes(source_str, AES_KEY)
decrypt_str = decrypt_by_aes(encrypt_str, AES_KEY)
print(encrypt_str)
print(decrypt_str)
输出结果:
v1Y+LCYilaKuVd9jXGW4OG6wQrmakZhhT7CDN48lliM=
不予の测试笔记
AES的CBC 模式实现
# -*- coding: utf-8 -*-
import base64
from Crypto.Cipher import AES
class EncryptDate:
def __init__(self, key, iv):
self.key = key.encode("utf-8") # 初始化密钥
self.iv = iv.encode("utf-8") # 初始化偏移量
self.length = 16 # 初始化数据块大小
self.aes = AES.new(self.key, AES.MODE_CBC, self.iv) # 初始化AES,ECB模式的实例
# 截断函数,去除填充的字符
self.unpad = lambda s: s[0:-s[-1]]
def pad(self, text):
"""
填充函数,使被加密数据的字节码长度是block_size的整数倍
"""
count = len(text.encode('utf-8'))
add = self.length - (count % self.length)
entext = text + (chr(add) * add)
return entext
def encrypt(self, encrData): # 加密函数
a = self.pad(encrData)
res = self.aes.encrypt(a.encode("utf-8"))
msg = str(base64.b64encode(res), encoding="utf8")
return msg
def decrypt(self, decrData): # 解密函数
res = base64.decodebytes(decrData.encode("utf-8"))
msg_text = self.aes.decrypt(res)
decrypt_text = self.unpad(msg_text).decode('utf8')
return decrypt_text
if __name__ == '__main__':
aes_key = "0CoJUm6Qyw8W8jud"
aes_iv = "9999999999999999"
text_data = '不予の测试笔记'
encrypt_data = EncryptDate(aes_key, aes_iv).encrypt(text_data)
decrypt_data = EncryptDate(aes_key, aes_iv).decrypt(encrypt_data)
print("原始数据:", text_data)
print("加密后数据:", encrypt_data)
print("数据解密:", decrypt_data)
输出结果:
原始数据: 不予の测试笔记
加密后数据: DSiSraEccFNBbo5L7O60C4sZw9z+owwxfTi8fMFYYVM=
数据解密: 不予の测试笔记
RSA加密
RSA加密算法是一种非对称加密算法, 使用openssl ,keytools等工具生成一对公私钥对,使用被公钥加密的数据可以使用私钥来解密。
# -*- coding: utf-8 -*-
import rsa
import base64
# rsa加密
def rsaEncrypt(str):
# 生成公钥、私钥
(pubkey, privkey) = rsa.newkeys(1024)
print("公钥: ", pubkey)
print("私钥: ", privkey)
# 明文编码格式
content = str.encode('utf-8')
# 公钥加密
crypto = rsa.encrypt(content, pubkey)
# # 一般加密的密文会以base64编码的方式输出
b_res = base64.b64encode(crypto).decode()
return(b_res, privkey)
# rsa解密
def rsaDecrypt(str, pk):
# 私钥解密
str = base64.b64decode(str.encode())
content = rsa.decrypt(str, pk)
con = content.decode('utf-8')
return con
(a, b) = rsaEncrypt("不予の测试笔记")
print('加密后密文:', a)
content = rsaDecrypt(a, b)
print('解密后明文:', content)
输出结果:
公钥: PublicKey(113470524225910557322884041079730885629500891762564656647656493210767749547668213373094028584810486476685694392950833477491276179265755337717974938997270915920724776540032039593464817490125523868061678130911761061942123329506543626197368650416434554584363549666830839661425323410205940989023322707335471888693, 65537)
私钥: PrivateKey(113470524225910557322884041079730885629500891762564656647656493210767749547668213373094028584810486476685694392950833477491276179265755337717974938997270915920724776540032039593464817490125523868061678130911761061942123329506543626197368650416434554584363549666830839661425323410205940989023322707335471888693, 65537, 49057384888184532877406601155882858742790763495437798212531838177424865582550790510905995177106372336701595509862656449810608042225245460410166786907298318676412949734430422952998615505434350499917821657126361553083727322987072459664877185816829930588001976168732927196445249652057892467131716493395488174913, 42634469690852041372779335865769377507324089843269658005185029937283890025207576461770779563428903937547975990563042099326958533052937770882166072164786597159641161, 2661473803912649805246869624668668574550205591791588900635990794504918156173482653597243444437455173742897237144953732507167046192020136204937613)
加密后密文: hI2rGwCXvG/8Y1yDg/G4rQLVKl22UnD/bun08CITOMHyeY2J7MI5c+Ex2sUTb2KJO+6QHkDJpAv+Q70KLmeprxQVMdnwapRNFg6imds+QdffkT926pt0kmF95h71GWdH7PRuoB23JoSYkm5aiZUuwfp3lW+g0bJEbvtmkI0bD2s=
解密后明文: 不予の测试笔记
评论