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
相關文章
相關標籤/搜索