python 加密解密(base64, AES)

1. 使用base64

s1 = base64.encodestring('hello world')
s2 = base64.decodestring(s1)
print s1, s2

结果css

1
2
aGVsbG 8 gd 29 ybGQ=
hello world

Base64编码,64指A-Z、a-z、0-九、+和/这64个字符,还有“=”号不属于编码字符,而是填充字符。为何发明这么个编码呢,这个编码的原理很简单,“破解”也很容易,缘由是电子邮件刚出来的时候,只传递英文字符,这没有问题,可是后来,中国人,日本人都要发email,这样问题就来了,由于这些字符有可能会被邮件服务器或者网关当成命令处理,故必须得有一种编码来对邮件进行加密,可是加密的目的是为了可以使得一些原始的服务器不出问题(如今服务器早已经能处理这些乱七八糟得状况了,不过由于已经造成了一套规范,因此邮件仍是得通过Base64编码才能传递)。html

优势:方法简单算法

缺点:不保险,别人拿到密文能够本身解密出明文安全

编码原理:将3个字节转换成4个字节((3 X 8)=24=(4X6)),先读入3个字节,每读一个字节,左移8位,再右移四次,每次6位,这样就有4个字节了。
解码原理:将4个字节转换成3个字节,先读入4个6位(用或运算),每次左移6位,再右移3次,每次8位,这样就还原了。服务器

2. 使用pycrypto模块

复制代码
>>> from Crypto.Cipher import AES
>>> obj = AES.new('This is a key123', AES.MODE_CBC, 'This is an IV456')
>>> message = "The answer is no"
>>> ciphertext = obj.encrypt(message)
>>> ciphertext
'\xd6\x83\x8dd!VT\x92\xaa`A\x05\xe0\x9b\x8b\xf1'
>>> obj2 = AES.new('This is a key123', AES.MODE_CBC, 'This is an IV456')
>>> obj2.decrypt(ciphertext)
'The answer is no'
复制代码

高级加密标准(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(初始向量,加密第一块明文)加密(明文)和解密(密文)。编码

再来一例加密

复制代码
#coding: utf8
import sys
from Crypto.Cipher import AES
from binascii import b2a_hex, a2b_hex
 
class prpcrypt():
    def __init__(self, key):
        self.key = key
        self.mode = AES.MODE_CBC
     
    #加密函数,若是text不是16的倍数【加密文本text必须为16的倍数!】,那就补足为16的倍数
    def encrypt(self, text):
        cryptor = AES.new(self.key, self.mode, self.key)
        #这里密钥key 长度必须为16(AES-128)、24(AES-192)、或32(AES-256)Bytes 长度.目前AES-128足够用
        length = 16
        count = len(text)
        add = length - (count % length)
        text = text + ('\0' * add)
        self.ciphertext = cryptor.encrypt(text)
        #由于AES加密时候获得的字符串不必定是ascii字符集的,输出到终端或者保存时候可能存在问题
        #因此这里统一把加密后的字符串转化为16进制字符串
        return b2a_hex(self.ciphertext)
     
    #解密后,去掉补足的空格用strip() 去掉
    def decrypt(self, text):
        cryptor = AES.new(self.key, self.mode, self.key)
        plain_text = cryptor.decrypt(a2b_hex(text))
        return plain_text.rstrip('\0')
 
if __name__ == '__main__':
    pc = prpcrypt('keyskeyskeyskeys')      #初始化密钥
    e = pc.encrypt("00000")
    d = pc.decrypt(e)                     
    print e, d
    e = pc.encrypt("00000000000000000000000000")
    d = pc.decrypt(e)                  
    print e, d 
复制代码

运行结果spa

1
2
a 9755 fd 70 d 8 d 6 db 65 a 6 fac 12 d 4797 dde  00000
2 c 1969 f 213 c 703 ebedc 36 f 9 e 7 e 5 a 2 b 88922 ac 938 c 983201 c 200 da 51073 d 00 b 2 00000000000000000000000000