本文是向大家介绍python中常见的一些加密方式,在使用python的时候遇到数据加密的情况时,可以根据实际场景来选择加密的方式对数据进行加密,加强数据传输的安全性。
日常工作中经常会看到各种加密算法,今天给大家带来的是python中常用的几种加密方式分享。相信大家都很熟悉了,其实各个编程语言中都有对应的加密模块,只用导入对应的依赖包,就可以轻松用起来,如果你会其中一种语言的加密,那么今天的分享内容对你来说绝对是so easy啦~
数据加密的基本过程就是对原来为明文的文件或数据按某种算法进行处理,使其成为不可读的一段代码为“密文”,使其只能在输入相应的密钥之后才能显示出原容,通过这样的途径来达到保护数据不被非法人窃取、阅读的目的。
在Python提供了encode和decode作为编码器和译码器,直接使用encode就可以起到加密的效果(加密后的结果为十六进制),如下所示:
str = '高阳捷迅' estr = str.encode('utf-8') print(estr) dstr = estr.decode('utf-8') print(dstr) # 结果 b'\xe9\xab\x98\xe9\x98\xb3\xe6\x8d\xb7\xe8\xbf\x85' 高阳捷迅
利用binascii模块可以将十六进制显示的字节转换成我们在加解密中更常用的显示方式:
str = '高阳捷迅' estr = str.encode('utf-8') # 将字符串转为为16进制,将encode后的编码进行优化 b2a = binascii.b2a_hex(estr) print(b2a) # 将优化好的b2a退回成encode编码 a2b = binascii.a2b_hex(b2a) print(a2b) # 结果 b'e9ab98e998b3e68db7e8bf85' b'\xe9\xab\x98\xe9\x98\xb3\xe6\x8d\xb7\xe8\xbf\x85'
Base64是网络上最常见的用于传输8Bit字节码的编码方式之一,Base64模块会使用65个(A~Z a~z 0~9 + / =)字符(计算机从0开始计数)来表示任意的二进制数据。
BASE64加密后产生的字节位数是8的倍数,如果不够位数会以=符号填充
str = '高阳捷迅' estr = str.encode('utf-8') # 加密 base64_estr = base64.b64encode(estr) print('base64加密为:', base64_estr) # 解密 base64_dstr = base64.b64decode(base64_estr) print('base64解密为:', base64_dstr) print('base64解密后字节解码结果为:', base64_dstr.decode('utf-8')) # 结果 base64加密为: b'6auY6Ziz5o236L+F' base64解密为: b'\xe9\xab\x98\xe9\x98\xb3\xe6\x8d\xb7\xe8\xbf\x85' base64解密后字节解码结果为: 高阳捷迅
MD5加密(信息-摘要算法Message-Digest Algorithm)是一种被广泛使用的密码散列函数,可以产生出一个128位(16字节)的散列值(hash value),用于确保信息传输完整一致。MD5是最常见的摘要算法,速度很快,生成结果是固定的128 bit字节,通常用一个32位的16进制字符串表示。
在Python3中使用hashlib模块进行操作,hashlib提供了常见的摘要算法,如MD5,SHA1等等
4.1基础用法
# 创建hash对象 hl = hashlib.md5() # 向hash中添加需要做hash运算的字符串 hl.update(estr) # 获取字符串的hash值 hash1 = hl.hexdigest() print('这是md5加密的:', hash1) # 结果 这是md5加密的: 477896a57b157d496b5b7711912335ea
4.2双层加密
# 双重加密 # 像上面那种实现方式,没有传递参数,则md5遵守一个规则,生成同一个对应关系,如果加了参数,就是在原来加密的基础上再加密一层,这样话参数只有自己知道,防止被撞库,因为别人永远拿不到这个参数 h2 = hashlib.md5(bytes(str, encoding='utf-8')) hash2 = h2.hexdigest() print('查看此时的hash值为:', hash2) h2.update(bytes(str, encoding='utf-8')) print('双层加密后的值为:', h2.hexdigest()) # 结果 查看此时的hash值为: 477896a57b157d496b5b7711912335ea 双层加密后的值为: 5e3b66ae2349249ee1cf3606ff1365ea
4.3SHA1加密
SHA1(安全哈希算法Secure Hash Algorithm)算法是基于MD5的一种加密算法,加密后的数据长度会比MD5更长,安全性更高但是效率也会变的更慢
# sha1加密 str = '高阳捷迅' estr = str.encode('utf-8') s1 = hashlib.sha1(estr).hexdigest() print('sha1加密后的结果为:',s1) # 结果 sha1加密后的结果为: f63b6e759e00f4ec27e2974c67e0106be5fc178f
HMAC(散列消息鉴别码Hash Message Authentication Code)加密算法是一种安全的基于hash函数和共享秘钥的消息认证协议
import hashlib import hmac str = '高阳捷迅' estr = str.encode('utf-8') '''hmac加密''' # new里面需要传入一个秘钥 hl = hmac.new(b'abcdef', estr, hashlib.md5) hash1 = hl.hexdigest() print('hmac加密后的值为:', hash1) # 结果 hmac加密后的值为: a593b1377202570c16b2d5d1db472d52
DES(数据加密标准Data Encrypion Standard)属于对称加密算法,它是一个分组加密算法,典型的DES以64位为分组对数据加密,加密和解密是同样的密钥。
注意:密钥必须为8位
import binascii from pyDes import des, CBC, PAD_PKCS5 def des_encrypt(secret_key, s): iv = secret_key k = des(secret_key, CBC, iv, pad=None, padmode=PAD_PKCS5) en = k.encrypt(s, padmode=PAD_PKCS5) return binascii.b2a_hex(en) def des_decrypt(secret_key, s): iv = secret_key k = des(secret_key, CBC, iv, pad=None, padmode=PAD_PKCS5) de = k.decrypt(binascii.a2b_hex(s), padmode=PAD_PKCS5) return de # key必须为8位 secret_key = des_encrypt('gaoyang1', '19e.com.cn') print('des加密后的串为:', secret_key) clear_str = des_decrypt('gaoyang1', secret_key) print('des解密后的串为:', clear_str) # 结果 des加密后的串为: b'c1d12110986bb4e96e78a6bea3c1697c' des解密后的串为: b'19e.com.cn'
AES(高级加密标准Advanced Encryption Standard)在密码学中又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准。这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用。经过五年的甄选流程,高级加密标准由美国国家标准与技术研究院(NIST)于2001年11月26日发布于FIPS PUB 197,并在2002年5月26日成为有效的标准。2006年,高级加密标准已然成为对称密钥加密中最流行的算法之一
注意:必须是16位字节或者24位字节或者32位字节(因为python3的字符串是unicode编码,需要 encode才可以转换成字节型数据)
AES加密方式有五种:
1.电码本模式(Electronic Codebook Book (ECB)
2.密码分组链接模式(Cipher Block Chaining (CBC))
3.计算器模式(Counter (CTR))
4.密码反馈模式(Cipher FeedBack (CFB))
5.输出反馈模式(Output FeedBack (OFB))
本次分享最常用且简单的一种模式:ECB模式
首先要安装模块:
python 在 Windows下使用AES时要安装的是pycryptodome 模块pip install pycryptodome
python 在 Linux下使用AES时要安装的是pycrypto模块pip install pycrypto
# 需要补位,str不是16的倍数那就补足为16的倍数 def add_to_16(value): while len(value) % 16 != 0: value += '\0' return str.encode(value) # 返回bytes # 加密方法 def encrypt(key, text): aes = AES.new(add_to_16(key), AES.MODE_ECB) # 初始化加密器 encrypt_aes = aes.encrypt(add_to_16(text)) # 先进行aes加密 encrypted_text = str(base64.encodebytes(encrypt_aes), encoding='utf-8') # 执行加密并转码返回bytes return encrypted_text # 解密方法 def decrypt(key, text): aes = AES.new(add_to_16(key), AES.MODE_ECB) # 初始化加密器 base64_decrypted = base64.decodebytes(text.encode(encoding='utf-8')) # 优先逆向解密base64成bytes decrypted_text = str(aes.decrypt(base64_decrypted), encoding='utf-8').replace('\0', '') # 执行解密密并转码返回str return decrypted_text secret_key = encrypt('gaoyangjiexun', '19e.com.cn') print('aes加密后的串为:', secret_key) clear_str = decrypt('gaoyangjiexun', secret_key) print('aes解密后的串为:', clear_str) # 结果 aes加密后的串为: cHwQLJxmKe0ho9hgUxNvlg== aes解密后的串为: 19e.com.cn
若要使用CBC模式,则将文中的AES.MODE_ECB换成AES.MODE_CBC,同时加上加上偏移量iv AES.new(add_to_16(key), AES.MODE_ECB,iv)即可
RSA(Rivest-Shamir-Adleman)是一种非对称加密算法,在公开秘钥加密和电子商业中广泛使用,它被普遍认为是目前比较优秀的公钥方案之一。
消息传递前需要先生成公钥和私钥,发送方将待发送消息用公钥加密,发送给接收方。接收方收到消息后,用私钥解密。在这个过程中,公钥负责加密,私钥负责解密,消息在传输过程中即使被截获,攻击者由于没有私钥,无法破解截获的消息。
非对称加密算法的加解密速度低于对称加密算法,但是安全性更高
因为RSA加密算法的特性,RSA的公钥私钥都是10进制的,但公钥的值常常保存为16进制的格式,所以需要将其用int()方法转换为10进制格式
import base64 from Crypto import Random from Crypto.PublicKey import RSA from Crypto.Cipher import PKCS1_v1_5 as Cipher_pkcs1_v1_5 class RSATest(): """ RSA加密是一种非对称加密,通常使用公钥加密,私钥解密,私钥签名,公钥验签。 在公开密钥密码体制中,加密密钥(即公开密钥)PK是公开信息,而解密密钥(即秘密密钥)SK是需要保密的. RSA算法通常是先生成一对RSA密钥,其中之一是保密密钥,由用户保存;另一个为公开密钥,可对外公开,甚至可在网络服务器中注册。 """ def __init__(self): """RSA 生成公钥私钥""" self.rsa_create_key() # 1、生成公钥私钥 def rsa_create_key(self): """RSA 生成公钥私钥""" random_generator = Random.new().read # rsa算法生成实例 rsa = RSA.generate(1024, random_generator) private_pem = rsa.exportKey() with open("private.pem", "wb") as f: f.write(private_pem) public_pem = rsa.publickey().exportKey() # 公钥生成并保存 with open("public.pem", "wb") as f: f.write(public_pem) # 2、加密(使用公钥加密) def rsa_encode(self, message=""): """RSA 加密(使用公钥加密)""" msg = message # .decode("utf-8") # python2 中文需要decode utf8 rsakey = RSA.importKey(open("public.pem").read()) cipher = Cipher_pkcs1_v1_5.new(rsakey) # 创建用于执行pkcs1_v1_5加密或解密的密码 cipher_text = base64.b64encode(cipher.encrypt(msg.encode('utf-8'))) return cipher_text.decode('utf-8') # 3、解密(使用私钥解密) def rsa_decode(self, cipher_text=""): """RSA 解密(使用私钥解密)""" encrypt_text = cipher_text.encode('utf-8') rsakey = RSA.importKey(open("private.pem").read()) cipher = Cipher_pkcs1_v1_5.new(rsakey) # 创建用于执行pkcs1_v1_5加密或解密的密码 text = cipher.decrypt(base64.b64decode(encrypt_text), "解密失败") return text.decode('utf-8') password = '123456' rsa_t = RSATest() rsa_t.rsa_create_key() encrypted_text = rsa_t.rsa_encode("高阳捷迅") decrypted_text = rsa_t.rsa_decode(encrypted_text) print('加密后:', encrypted_text) print('解密后:', decrypted_text) # 结果 加密后: lewyZbz2BlB+CoasaauuyyEPFXLFdOLwsno8g6dvF3rA4XaHW9/7j1GcGWx7Y+dt62GYJW+4c4PhtxjC0/3EHBlQOno9V+2wpiK/5DzkraW7riTlZ1or+9wZbGw3G+L9ERxa9dMOg8IyrY0xEOre/o+xGsLLAfL77GgDznJsy9E= 解密后: 高阳捷迅
python中使用import Crypto包可能会有找不到的情况,你可能会有疑问,我明明pip install了啊,这个时候不要怀疑自己,没错,你确实是下载了依赖了,在引入的时候要注意,两个C为大写,同时找到你python包下载的路径,在python安装路径下的\Lib\site-package里面,可以看到 刚刚pip install Crypto安装的包名变成了小写的crypto,无需惊慌,解决办法是手动将小写c改为大写C即可,完美解决
本文是笔者学习的时候写的代码,结构比较分散,在项目中应用时最好封装成一个公共的工具类,人人可用。另外,本文只写了一些比较常用的加密方式,分享的是基本使用方法和经验,文中若有错误之处,请各位多多包涵~