base64
Base64编码,64指A-Z、a-z、0-9、+和/这64个字符,还有“=”号不属于编码字符,而是填充字符。为什么发明这么个编码呢,这个编码的原理很简单,“破解”也很容易,原因是电子邮件刚出来的时候,只传递英文字符,这没有问题,但是后来,中国人,日本人都要发email,这样问题就来了,因为这些字符有可能会被邮件服务器或者网关当成命令处理,故必须得有一种编码来对邮件进行加密,但是加密的目的是为了能够使得一些原始的服务器不出问题(现在服务器早已经能处理这些乱七八糟得情况了,不过因为已经形成了一套规范,所以邮件还是得经过Base64编码才能传递)。
优点:方法简单
缺点:不保险,别人拿到密文可以自己解密出明文
编码原理:将3个字节转换成4个字节((3 X 8)=24=(4X6)),先读入3个字节,每读一个字节,左移8位,再右移四次,每次6位,这样就有4个字节了。
解码原理:将4个字节转换成3个字节,先读入4个6位(用或运算),每次左移6位,再右移3次,每次8位,这样就还原了。
AES
级加密标准(Advanced Encryption Standard,AES),是美国联邦政府采用的一种区块加密标准。这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用。经过五年的甄选流程,高级加密标准由美国国家标准与技术研究院(NIST)于2001年11月26日发布于FIPS PUB 197,并在2002年5月26日成为有效的标准。2006年,高级加密标准已然成为对称密钥加密中最流行的算法之一。
AES只是个基本算法,实现AES有若干模式。其中的CBC模式因为其安全性而被TLS(就是https的加密标准)和IPSec(win采用的)作为技术标准。简单地说,CBC使用密码和salt(起扰乱作用)按固定算法(md5)产生key和iv。然后用key和iv(初始向量,加密第一块明文)加密(明文)和解密(密文)。
PyCrypto是一个免费的加密算法库,支持常见的DES、AES加密以及MD5、SHA各种HASH运算。AES加密的初始密钥,根据AES规范,可以是16字节、24字节和32字节长;其实完全可以由用户输入的口令+salt获得;iv,这里使用了Crypto模块中的Random模块,读取其16字节的数据作为iv的值,AES的分块大小固定为16字节。
AES.new(key, AES.MODE_CBC,iv)函数,这步可以指定加密模式,这里选择的是CBC模式;data数据长度是否为16字节块的整数倍,从而进行适当的Padding,这里的关键是利用'%'运算判断是否是16字节的整数倍,然后在尾部追加(16-x)个填充字符;生成的cipher对象的encrypt方法加密数据,注意这里与iv进行了一次异或。
# encoding:utf-8 import base64 from Crypto.Cipher import AES from Crypto import Random
def encrypt(data, password): bs = AES.block_size pad = lambda s: s + (bs - len(s) % bs) * chr(bs - len(s) % bs) iv = Random.new().read(bs) cipher = AES.new(password, AES.MODE_CBC, iv) data = cipher.encrypt(pad(data)) data = iv + data return data def decrypt(data, password): bs = AES.block_size if len(data) <= bs: return data unpad = lambda s : s[0:-ord(s[-1])] iv = data[:bs] cipher = AES.new(password, AES.MODE_CBC, iv) data = unpad(cipher.decrypt(data[bs:])) return data if __name__ == '__main__': data = 'd437814d9185a290af20514d9341b710' password = '78f40f2c57eee727a4be179049cecf89' #16,24,32位长的密码 encrypt_data = encrypt(data, password) encrypt_data = base64.b64encode(encrypt_data) print 'encrypt_data:', encrypt_data encrypt_data = base64.b64decode(encrypt_data) decrypt_data = decrypt(encrypt_data, password) print 'decrypt_data:', decrypt_data