AES对称加密
Posted 善良说
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AES对称加密相关的知识,希望对你有一定的参考价值。
这些天因为工作需要,对接了一个由Java编写的网站后台接口,他们所使用的认证方式是AES对称加密,然后就在这几天研究了一下这种加密方法。说实话内部原理实在是太过于硬核,自己的算法着实是差,看一眼就头疼,如果有硬核的读者,推荐一个大神关于AES的介绍:
https://github.com/matt-wu/AES
这里详细描述了AES算法的设计思想,以及各种模式下的底层实现,反正我是解释不明白,如果有兴趣的可以去看看。
虽然算法看不懂,但也不能耽误了工作,毕竟还要吃饭,只好抛弃底层的实现,反正Python有那么多强大的库,肯定有一款适合你。
于是我就找到了Crypto这个库,可以直接引用它里面的AES算法,通过简单的实例创建引用就可以很快的完成加密和解密。
但是理想和现实还是有出入的,当我以为一切都很简单的时候,各种问题就都找上门来了。不过最后还是通过我的聪明才智都给一一解决了。
废话不多说直接上代码
import base64
import re
import urllib.parse
from Crypto.Cipher import AES
class AesEcbCtr:
def __init__(self, key):
self.key = key.encode("utf8") # 定义密钥
self.mode = AES.MODE_ECB # 加密模式
self.bs = 16 # block size
self.PADDING = lambda s: s + (self.bs - len(s) % self.bs) * chr(self.bs - len(s) % self.bs) # 填充方式:PKCS5Padding
def encrypt(self, text):
"""加密"""
generator = AES.new(self.key, self.mode) # 创建AES实例
crypt = generator.encrypt(self.PADDING(text).encode("utf8"))
# crypted_str = binascii.b2a_hex(crypt) # 也可以HEX进行输出
base_str = base64.b64encode(crypt) # 输出Base64
result = base_str.decode()
return urllib.parse.quote(result)
def decrypt(self, text):
"""解密"""
generator = AES.new(self.key, self.mode)
text += (len(text) % 4) * '='
decrpyt_bytes = base64.b64decode(text) # Base64解码
meg = generator.decrypt(decrpyt_bytes)
# 去除解码后的非法字符
try:
result = re.compile('[\\x00-\\x08\\x0b-\\x0c\\x0e-\\x1f\n\r\t]').sub('', meg.decode())
except Exception:
result = '解码失败,请重试!'
return result
这段代码是我根据网络上大神的思路再结合实际使用写出来的,这里要有几个注意事项:
1.密钥长度一定要是 16(AES-128)、24(AES-192)、或32(AES-256)Bytes长度,不然创建实例就是直接崩溃2.无论密钥或者要加密的字符串,都必须转换成bytes字节码方式传递到方法中,这里在AES源码中也强调了参数的接收类型。3.使用前一定要确认好加密模式,填充方式以及编码格式,任何一个不一致双方都无法正常加解密4.加密的内容要作为url参数时,要注意参数的安全格式,即使用urllib.parse.quote(result)方法转码,以防止部分特殊字符读取的问题
大概注意的就这么多,没一点都是坑了我好久的,就拿第二条来说,网络上的大神都没有将字符串转换为byte字节码,不知道是版本的问题还是什么,最后选择相信自己的判断,果断转换了字节,分分钟就搞定。
其实AES算法加密还有很多值得研究的地方,还是很深奥的,但是吃饭要紧嘛,做完这个还有其它的问题等着我呢,所以AES就简单的说到这里吧!
以上是关于AES对称加密的主要内容,如果未能解决你的问题,请参考以下文章
更新实现代码对称加密与解密剖析:AES,高级加密标准(Advanced Encryption Standard,缩写AES)