模塊_使用M2Crypto加密數據

加解密數據、操做密鑰、操做SSL協議廣泛使用了OpenSSL。雖然還有其它的使用C/C++開發的加密處理庫,可是Python環境下支持最好的使用最普遍的仍是OpenSSL。php

據python.org官方網站,目前有幾個庫提供了加密功能。html

PyOpenSSL。這個庫是比較早的,可是做者已經中止開發,而且只支持SSL功能,而沒有提供加密、解密、X509等功能的包裝,最好不要繼續使用這個庫了。 M2Crypto。完整支持OpenSSL。單元測試比較全面。在原有C語言API的基礎上提供了Python的封裝。 ssl4py。與M2Crypto相似。可是徹底使用C編寫,與OpenSSL的API很相似。估計是用SWIG之類的工具生成的。據我本人看他的源代碼,在調用EVP_CipherUpdate()函數的時候,輸出大小沒有計算正確。此錯誤會形成數據不正確,是一個比較嚴重的BUG。我估計應該還有其它的BUG存在,可能比較不成熟。有使用過的來講一下吧。 ezPyCrypto。全名是Python Cryptography Toolkit。據水木網友josephpei說,這個很強大,有望進入官方CPython的標準庫內。不使用OpenSSL的API。 PyCrypto。這個庫目前使用也至關普遍。不使用OpenSSL的API 考慮到OpenSSL使用很普遍。我決定在開發中使用M2Crypto。python

M2Crypto的API手冊處於:http://www.heikkitoivonen.net/m2crypto/api/web

目前,截止到2009年10月23日,官網上提供的M2Crypto for Python 2.6(win32)安裝包是不正確的。由於它提供的0.19版本並無兼容0.20。因此須要下載M2Crypto的源代碼自行編譯。如下是編譯的步驟:算法

下載安裝mingw32:http://www.mingw.org. 下載安裝 swig: http://www.swig.org。選擇下載SWIG for python(win32)的版本。而且把swig的路徑加入$PATH環境變量內。 下載安裝OpenSSL的Windows版本:http://www.slproweb.com/products/Win32OpenSSL.html 把OpenSSL的include文件夾複製到Python的include文件夾內。把OpenSSL的幾個庫文件(*.a)複製到mingw32的lib文件夾內。 OpenSSL for windows的庫文件與for Unix版本名字有些不大同樣。須要把libeay32.dll.a更名liblibeay32.a,把libssl32.dll.a更名libssleay32.a。測試的版本是0.9.8h 運行setup.py build -c mingw32 bdist_wininst 一切順利的話在dist文件夾下能夠找到安裝程序。 (附記)M2Crypto主頁提供了一處描述如何在windows平臺下使用msvc編譯openssl和M2Crypto的連接。通過試驗,該方法不能在mingw32下成功。不過在一個用戶評論上描述了mingw32下的方法,當時沒仔細看,害我搞了半天沒成功。(再附記)截止2012年1月1日止,在M2Crypto提供了最新版本的Windows安裝程序。因此本身編譯一般是不必的了。編程

通過我測試,編譯後的M2Crypto雖然導入正常,可是一旦使用BIO進行文件操做,M2Crypto就會異常退出。並打印出No AppLink這樣的錯誤信息。若是不使用BIO的話,好像又沒啥問題。windows

安裝程序缺乏openssl的幾個動態連接庫,若是要發佈這些個安裝程序,應該把將OpenSSL的動態連接庫一塊兒打包進去。api

下面是幾個模塊的大體介紹:sass

M2Crypto.BIO 用於操做IO抽象類型。 M2Crypto.BN 用於操做大數 M2Crypto.DH 用於操做Diffie-Hellman key exchange protocol M2Crypto.EVP 高級的加密解密接口。與直接使用具體的加密算法不一樣。使用該接口,能夠用相同的編程方式,調用不一樣的算法處理數據。它包含了對稱加密算法與非對稱加密算法的支持。 M2Crypto.EC 橢圓曲線非對稱加密算法 M2Crypto.DSA DSA非對稱加密算法 M2Crypto.RSA RSA非對稱加密算法 M2Crypto.Rand 操做隨機數 M2Crypto.SSL 操做SSL協議 M2Crypto.X509 操做X509 接下來,咱們經過平常的編程任務來看看如何使用這些接口。安全

如何使用MD五、SHA1等消息散列算法。

雖然OpenSSL提供了直接操做MD五、SHA1算法以及blowfish等各類對稱加密算法的API,可是M2Crypto並無將其包含進來。不過也好,各類算法都有各自的API,記起來麻煩。經過M2Crypto.EVP,咱們仍然能夠調用這些算法。下面是一個MD5的例子:

def md5(s): #在構造函數中傳入算法的名字能夠選擇不一樣的消息散列算法 m=EVP.MessageDigest("md5") m.update(s) return m.digest() #或者m.final() 經常使用的散列算法還有SHA1。使用方法與MD5相似,只是構造函數是:

m=EVP.MessageDigest("sha1") 使用對稱加密算法加密數據。

如前所述,咱們須要使用EVP.Cipher這個比較抽象的API,而不是具體的算法。與EVP.MessageDigest()相似,EVP.Cipher主要提供四個函數:

EVP.Cipher.init(self, alg, key, iv, op, key_as_bytes=0,
d='md5', salt='12345678', i=1, padding=1) EVP.Cipher.update(self, data) EVP.Cipher.final() EVP.Cipher.set_padding(self, padding=1) 下面是一段使用blowfish算法將明文"fish is here"加密成密文的函數代碼:

def blowfish_encrypt(s, password): out=StringIO() m=EVP.Cipher("bf_ecb", password, "123456", 1, 1, "sha1", "saltsalt", 5, 1) out.write(m.update(s)) out.write(m.final()) return out.getvalue() 能夠發現,最主要的是Cipher的構造函數:

EVP.Cipher.init(self, alg, key, iv, op, key_as_bytes=0,
d='md5', salt='12345678', i=1, padding=1) alg是指算法的名字,OpenSSL支持如下算法:

des_cbc des_ecb des_cfb des_ofb des_ede_cbc des_ede des_ede_ofb des_ede_cfb ------- 2DES算法 des_ede3_cbc des_ede3 des_ede3_ofb des_ede3_cfb ------- 3DES算法 desx_cbc rc4 rc4_40 ------- 密鑰爲40位的RC4算法 idea_cbc idea_ecb idea_cfb idea_ofb idea_cbc rc4_cbc rc2_ecb rc2_cfb rc2_ofb rc2_40_cbc rc2_64_cbc bf_cbc bf_ecb bf_cfb bv_ofb ------- Blowfish算法 cast5_cbc cast5_ecb cast5_cfb cast5_ofb rc5_32_12_16_cbc rc5_32_12_16_ecb rc5_32_12_16_cfb rc5_32_12_16_ofb 能夠注意到各類算法的名字除了算法自己的名字外,還帶有各類後綴。好比blowfish有bf_cbc, bf_ecb多個名字。這些後綴是什麼意思呢?在本文的最後附帶了我另外一份學習筆記,其中有不完整的解釋。如今先來看看技術上如何使用這些算法吧。

key是加密所用的密鑰。傳入的是一段二進制數據,其長度是密鑰的長度。不過,若是後面的參數key_as_bytes==1,那key是一個普通的任意長度的字符串,將與salt, i參數一塊兒生成一個真正的密鑰。好比說,假設算法alg的密鑰長度是16,若是key_as_bytes==0,那麼key應該傳入"\xff\xff"兩個字節的字符串。若是key_as_bytes==1,則能夠傳入相似於123456這樣子的字符串。

iv是指初始向量。與加密算法所使用的加密塊的長度一致。有些加密算法並不使用iv這個變量。若是key_as_bytes==1。雖然OpenSSL的key_to_bytes()函數可使用alt, key ,salt ,d, i四個參數生成真正的密鑰和iv。可是M2Crypto內部並無這樣子作。而是直接使用原來的iv.若是iv的長度超過了加密算法所使用的加密塊的長度,超過的長度會被截取。

op用於指示解密或者加密操做。op==1表示加密操做;op==0表示解密操做。在作逆操做的時候,除了op不同,其它參數應當保持一致。

key_as_bytes參數如前所述。若是key_as_bytes==1。M2Crypto會使用alg, key, d, salt, i五個參數生成真正的密鑰(注意,沒有使用IV)。若是key_as_bytes==0,表示傳入的是真正的密鑰,d, salt, i三個參數就沒有意義了。

d是指生成密鑰時所使用的散列算法。能夠選擇md5, sha1等。最好使用sha1,由於md5的破解看來只是時間問題了。

salt是指生成密鑰時所使用的鹽。M2Crypto默認是123456。

i是指生成密鑰時所迭代的次數。迭代次數越多,使用暴力攻擊就越不容易。

padding是指填充加密塊。大多數加密算法是以塊爲單位進行加密的。明文被切分爲一個個固定大小的塊。而後分別進行加密,獲得與原來大小一致的加密塊。可是明文的長度並不必定是加密塊長度的整數倍。所以在處理最後一個塊時須要進行填充。經常使用的填充算法是PKCS padding.若是沒有容許padding而且最後一段明文不足以達到加密塊的長度。EVP_EncryptFinal_ex()會返回一個錯誤。若是padding是容許的,可是密文最後並無包含一個正確的填充塊,EVP_DecryptoFinal()就會返回一個錯誤。padding默認是容許的。

生成RSA密鑰

DSA與RSA是比較經常使用的兩種非對稱加密算法。他們的使用方法與特性正如他們的名字,基本上大同小異。在OpenSSL內,使用與其它名字同樣的結構體來表示這兩個算法的密鑰。在M2Crypto裏,也是如此。只是在M2Crypto裏DSA與RSA是兩個類,帶有簽名、驗證等方法。

通常並不構造RSA與DSA類。而使用相應的工廠方法。好比生成RSA密鑰:

from M2Crypto import BIO, RSA

#此函數生成一個1024位的RSA密鑰,將其轉化成PEM格式返回 def genrsa(): bio=BIO.MemoryBuffer() rsa=RSA.gen_key(1024, 3, lambda *arg:None) rsa.save_key_bio(bio, None) return bio.read_all() RSA.gen_key()是一個工廠方法,它返回一個存儲了新的RSA密鑰的RSA.RSA()實例。它的方法簽名是:gen_key(bits, e, callback=keygen_callback)

bits參數是指RSA密鑰的長度,1024如下的RSA密鑰雖然尚未被破解,可是已經認爲是不安全的了。做爲CA使用的RSA密鑰一般要求達到2048位以上。e是RSA算法的"public exponent"。功能是什麼?我也不大清楚,據OpenSSL的文檔說,這個函數一般是三個奇數3,17,65537之一。callback是一個回調函數。用於顯示生成密鑰的進度。具體請查閱OpenSSL的文檔。

這裏是OpenSSL中對應的函數原型:

#include <openssl/rsa.h> RSA *RSA_generate_key(int num, unsigned long e, void (*callback)(int,int,void *), void *cb_arg); 生成DSA密鑰

DSA算法相關的估計是另一夥人開發的。API有些不大同樣。它首先須要生成參數,而後才能生成密鑰。如下是一段代碼:

from M2Crypto import BIO, DSA #此函數生成一個1024位的DSA密鑰,將其轉化成PEM格式返回 def gendsa(): bio=BIO.MemoryBuffer() dsa = DSA.gen_params(1024, lambda *arg: None) dsa.gen_key() dsa.save_key_bio(bio,None) return bio.read_all() 能夠發現生成DSA密鑰時須要首先使用DSA.gen_params()生成DSA參數。gen_params()函數的第一個參數是DSA密鑰的長度,第二個密鑰與RSA.gen_key()的回調函數相同。DSA.gen_params()返回一個DSA類的實例。調用DSA.gen_key()方法生成密鑰。其它的與RSA相似。

載入DSA密鑰與RSA密鑰

RSA:

返回RSA類型:

load_key(file, callback=util.passphrase_callback) load_key_bio(bio, callback=util.passphrase_callback) load_key_string(string, callback=util.passphrase_callback) 返回RSA_pub類型:

load_pub_key(file) load_pub_key_bio(bio) DSA:

返回DSA類型:

load_params(file, callback=util.passphrase_callback) load_params_bio(bio, callback=util.passphrase_callback) load_key(file, callback=util.passphrase_callback) load_key_bio(bio, callback=util.passphrase_callback) 返回DSA_pub類型:

load_pub_key(file, callback=util.passphrase_callback) load_pub_key_bio(bio, callback=util.passphrase_callback) 這些函數大同小異。若是參數名字是file的話,表明的是一個文件名。若是參數名字是bio的話,表明的是一個BIO對像。BIO對象與Python的file對象相似都是用於表示一個能夠讀寫的相似於文件的類型。BIO對象除了能夠是一個普通的文件,還能夠是一個ssh鏈接,還能夠是一段內存(BIO.MemoryBuffer)。BIO.MemoryBuffer與Python的StringIO.StringIO相似。由於以前咱們提到我編譯的M2Crypto在進行文件IO的時候會異常退出,因此最好只使用BIO.MemoryBuffer。

在本文裏,提到密鑰,是同時指公鑰與私鑰。

在OpenSSL及大多數軟件裏,由於公鑰會被單獨分發出去,因此公鑰能夠單獨保存在公鑰文件裏。而密鑰的全部者既然保存私鑰,確定也會同時保存公鑰。故而私鑰並不會單獨保存到一個私鑰文件裏,而是和公鑰一塊兒保存在密鑰文件裏。

RSA類型的操做——使用RSA加密、解密、簽名、認證;保存RSA密鑰

RSA類型封裝了一些可使用RSA密鑰進行的操做。

首先,可使用len(rsa)得到RSA密鑰的長度。單位是位,一般使用1024位以上的密鑰纔是安全的。

def public_encrypt(self, data, padding):

使用公鑰進行加密。data是數據,是一段普通的字符串。而padding參數是指填充加密塊的模式。它是一個枚舉類型。根據OpenSSL的文檔,padding有四個取值:no_padding,pkcs1_padding,sslv23_padding,pkcs1_oaep_padding。最好是隻使用pkcs1_oaep_padding,由於它會在加密過程當中插入一些隨機數,防止相同的明文產生相同的密文,缺點是密文確定會比明文長不少。要注意的是,一次加密的明文不能太長,只能等於或者小於密鑰的長度。當padding==RSA.no_padding時由於沒有填充,因此要求len(data)==len(rsa)//8,不能多不能少。對於pkcs1_oaep_padding,必須小於等於len(rsa)//8-42。如前所述,len(rsa)是密鑰的長度,單位是位,換算成字節要除8。

def public_decrypt(self, data, padding):

使用公鑰進行解密。

def private_encrypt(self, data, padding):

使用私鑰進行加密。

def private_decrypt(self, data, padding):

使用公鑰進行加密。

由於RSA是一種非對稱加密算法。因此用私鑰加密的數據,要用公鑰才能解密。反之,用公鑰加密的數據,要用私鑰才能解密。一般在通訊中,發送方使用接收方的公鑰加密數據。_只有_接收方纔有私鑰可以解密數據。由於非對稱加密算法的速度通常比對稱加密算法慢,因此在一個連續的通訊過程當中,常常是發送方隨機生成一個對稱加密算法的密鑰,而後使用非對稱加密算法發送給接收方,之後全部的通訊過程都是使用這個隨機密鑰。只要保證每隔一段時間就換一個密鑰,這個通訊過程就跟直接使用非對稱加密算法同樣安全了。直接使用非對稱加密算法的狀況不多見。

非對稱算法還常常用於對數據進行簽名。簽名能夠保證發送方不可否認本身發送的數據是本身的。好比,在一個電子商務交易中,客戶下了一個訂單,不能等工廠已經生產完了才否定這個訂單是本身下的。簽名最簡單的辦法固然是使用發送方的私鑰進行加密。若是不使用發送方的公鑰就不能解密數據。反之,也能夠說,凡是可使用發送方的公鑰解密出數據,就說明數據是使用發送方的私鑰加密的。在現實生活中,人們通常是使用SHA1之類的散列算法算出數據的散列值,而後再用私鑰加密這個散列值。接收方接收到數據與散列值以後,一樣使用SHA1算法算出數據的散列值,與使用公鑰解密出來的散列值做對比。若是是同樣的,說明數據正確。若是不同,或者是在傳輸過程當中被更改了,或者根本不是發送方所發送的。

RSA算法提供了兩種簽名的方式,其分別多是不一樣的國際標準。我還不是很清楚。

第一組:

sign_rsassa_pss(self, digest, algo='sha1', salt_length=20) verify_rsassa_pss(self, data, signature, algo='sha1', salt_length=20) 這組API與下面兩個函數相似。看起來差很少的樣子,不過我沒有進行過測試。實際上OpenSSL中並無sign_rsassa_pss()這樣函數。它其實是分爲兩個步驟:RSA_padding_add_PKCS1_PSS()和RSA_private_encrypt()。而verify_rsassa_pss()函數則分爲RSA_public_decrypt()與RSA_verify_PKCS1_PSS()兩個步驟

第二組:

sign(self, digest, algo='sha1') verify(self, data, signature, algo='sha1') 這組API對應於OpenSSL中的RSA_sign()與RSA_verify()函數。分別是簽名與驗證。雖然sign()方法接收散列算法的名字做爲名字,但實際上digest參數應該是已經計算出的散列值。如下是對一段數據進行簽名的代碼:

#發送方對數據進行簽名 from M2Crypto import * m=EVP.EVP.MessageDigest("sha1") #先計算散列值 m.update("fish is here") digest=m.final() key_str=file("fish_private.pem", "rb").read() #讀入私鑰 key=RSA.load_key_string(key_str, util.no_passphrase_callback)

#簽名後獲得的數據。與原始數據一塊兒發送出去。 result=key.sign(digest, "sha1")

:::python #接收方驗證數據 from M2Crypto import * m=EVP.EVP.MessageDigest("sha1") #先計算散列值 m.update("fish is here") digest=m.final() #先計算散列值 cert_str=file("fish_public.pem", "rb").read() #讀入公鑰 mb=BIO.MemoryBuffer(cert_str)

#RSA模式沒有load_pub_key_string()方法,需自行使用MemoryBuffer cert=RSA.load_pub_key_bio(mb) cert.verify(digest, result, "sha1") #返回True/False 一個小型的CA,電子證書。

說到CA,不得不說到PKI認證體系。PKI體系是一個概念性的認證系統。它的基本原理是,通訊系統內全部節點都認可一個權威的機構,稱爲CA。全部參與通訊的節點都有一個電子證書,由該節點的公鑰和身份認證信息組成。CA覈查這個電子證書的身份信息是否正確。若是正確的話,就使用CA的祕鑰進行簽名。這樣,全部的通訊節點就可使用電子證書內包含的身份信息而沒必要親自核查了。

全部通訊節點都持有CA的電子證書。CA的電子證書是CA本身簽名的。在PKI系統運行以前,人們會事先設置好CA證書。

通訊節點生成電子證書的過程是:

通訊節點生成RSA或者DSA等非對稱加密算法的密鑰。 通訊節點生成電子證書請求文件(X509_Request)。其中包含通訊節點的身份信息、公鑰,而且用通訊節點的私鑰簽名。 CA讀取電子證書請求文件。覈查身份信息是否正確。若是身份信息正確就生成通訊節點的電子證書。其中包含CA的身份信息、通訊節點的身份信息、通訊節點的公鑰、電子證書的起始有效時間,電子證書的結束有效時間。一般還會記錄這是CA所頒發的第幾個證書。 生成非對稱加密算法的密鑰在以前已經有提到過了。接下來是如何生成證書請求文件的代碼:

from M2Crypto import *

#首先載入密鑰文件。此文件同時保存了通訊節點的私鑰與公鑰。 #這裏並不像以前直接使用 pkey_str=file("fish_private.pem", "rb").read() pkey=EVP.load_key_string(pkey_str, util.no_passphrase_callback) req=X509.Request() req.set_pubkey(pkey) #包含公鑰 #req.set_version(1)

#身份信息不是簡單的字符串。而是X509_Name對象。 name=X509.X509_Name()

#CN是Common Name的意思。若是是一個網站的電子證書,就要寫成網站的域名 name.CN="Goldfish"

#Organization Unit,一般是指部門吧,組織內單元 name.OU="Dev Department"

#Organization。一般是指公司 name.O="Besteam"

#State or Province。州或者省 name.ST="Fujian"

#Locale。 name.L="Quanzhou"

#國家。不能直接寫國家名字,好比China之類的,而應該是國家代碼。 #CN表明中國。US表明美國,JP表明日本 name.C="CN"

req.set_subject(name) #包含通訊節點的身份信息 req.sign(pkey, "sha1") #使用通訊節點的密鑰進行簽名 file("fish_req.pem", "wb").write(req.as_pem()) #寫入到文件 能夠發現,若是簡化那些設置身份信息的代碼,實際上就是三步:包含公鑰、包含身份信息、簽名。

接下來,咱們看看CA是如何給一個通訊節點發放證書的。

from M2Crypto import * import time

#首先讀取證書請求文件。 req_str=file("fish_req.pem", "rb").read()

#返回一個X509.Request類型表明證書請求文件 req=X509.load_request_string(req_str)

#首先驗證一下,是否是真的是使用它自己的私鑰簽名的。 #若是是,返回非0值。若是不是,說明這是一個非法的證書請求文件。 print req.verify(req.get_pubkey())

#接下來載入CA的電子證書。與CA的密鑰不同,CA的電子證書包含了CA的身份信息。 #CA的電子證書會分發給各個通訊節點。 ca_str=file("ca.pem", "rb").read() ca=X509.load_cert_string(ca_str)

#可使用check_ca()方法判斷這個證書文件是否是CA。 #本質是判斷它是否是自簽名。若是是的話,就返回非0值。若是不是的話就返回0。 #print ca.check_ca()

#接下來載入CA的密鑰 cakey_str=file("cakey.pem", "rb").read()

#通常CA的密鑰要加密保存。回調函數返回密碼 cakey=EVP.load_key_string(cakey_str, lambda *args:"1234")

#接下來開始生成電子證書 cert=X509.X509()

#首先,設定開始生效時間與結束生效時間 t = long(time.time()) + time.timezone #當前時間,單位是秒

#開始生效時間。證書的時間類型不是普通的Python datetime類型。 now = ASN1.ASN1_UTCTIME() now.set_time(t) nowPlusYear = ASN1.ASN1_UTCTIME() #結束生效時間 nowPlusYear.set_time(t + 60 * 60 * 24 * 365) #一年之後。 cert.set_not_before(now) cert.set_not_after(nowPlusYear)

#把證書請求附帶的身份信息複製過來 cert.set_subject(req.get_subject())

#設置頒發者的身份信息,把CA電子證書內身份信息複製過來 cert.set_issuer(ca.get_subject())

#序列號是指,CA頒發的第幾個電子證書文件 cert.set_serial_number(2)

#把證書請求內的公鑰複製過來 cert.set_pubkey(req.get_pubkey())

#使用CA的祕鑰進行簽名。 cert.sign(cakey, "sha1") file("fishcert2.pem", "wb").write(cert.as_pem())#保存文件。 補充:加密模式與初始向量,爲何對稱加密算法有各類後綴?

對稱加密算法除了要指明填充方式之外,在使用塊加密前還須要指定它所使用的模式。這個模式定義了Cipher如何應用加密算法。改變模式能夠允許一個塊加密程序變爲流加密程序。

分組密碼每次加密一個數據分組,這個分組的位數能夠是隨意的,通常選擇64或者128位。另外一方面,流加密程序每次能夠加密或解密一個字節的數據,這就使它比流加密的應用程序更爲有用。

ECB(Electronic Code Book:電碼本)

ECB是最簡單的模式,一樣的明文分組老是加密成相同的密文分組。這對於發送單一的塊數據來講是很是好的,如密鑰。但對執行一個加密的信息流來講不是很好,由於若是相同的明文屢次發送之後,一樣的密文也會被屢次發送。

ECB最大的弱點是對每個塊用相同的方式進行加密。若是咱們的密鑰或者數據不斷髮生變化,ECB是徹底安全的。可是若是相似的塊通過一樣的密鑰加密發出之後,攻擊者可能得到一些咱們並不想讓別人知道的信息。

CBC(Cipher Block Chaining:密碼分組連接)

CBC模式改變了加密方式,一樣的明文分組不必定加密或解密一樣的密文塊,所以解決了ECB存在的主要問題。CBC使用前一分組的信息加密當前分組。所以和ECB模式大不相同。這個方法依然存在問題,那就是相同的信息仍然加密成相同的密文,由於全部的分組是同時變成密文分組的。爲了解決這個問題,咱們引入一個Initialization Vector(初始化向量),也就是前不久有人問到的IV問題。IV僅僅是一個初始化加密程序的隨機數。它無需祕密保存,但隊每個信息來講它都是不一樣的,經過這個方式,即便有兩條相同的信息,只要他們有不一樣的IV,那麼他們加密後的密文也是不一樣的。從這個意義上來講,初始化向量無疑就和口令加密過程當中使用的鹽值是同樣的。

CBC很適合文本傳輸,但它每一次都須要傳送一個完整的數據塊,通常選8個字符。

CFB(Cipher FeedBack:密碼反饋)

CFB的工做方式與CBC相似,但它能夠執行更小的數據塊,典型的有8位,這很是適合加密像聊天對話這樣的信息,由於每次能夠發送單一的字節數據塊。

和CBC同樣,CFB也須要一個IV,且相同及鑰發送的每條信息的IV都必須是惟一的。

OFB(Output FeedBack:輸出反饋)

OFB除了在傳輸中能給數據提供更好的保護,防止數據丟失外,其餘和CFB相似。密文中一位出錯,也只形成明文中的一位出錯,其餘的方式會形成整個塊丟失。

和CBC以及CFB同樣,OFB也須要一個IV。

各類加密模式通常在密碼學的教程中能夠找到。

補充:X509電子證書的文件格式。

X509定義了用於存儲公鑰電子證書,證書撤回列表的文件格式。還定義了一個電子證書驗證的路徑算法。X509一般也稱爲PKIX for Public Key Infrastructure (X.509),這說明了它是PKI體系的一種實現方式。X509所使用的多種文件格式:

.DER - DER encoded certificate,是ASN.1的一種編碼規則。 .PEM - (Privacy Enhanced Mail) Base64 encoded DER certificate, enclosed between "-----BEGIN CERTIFICATE-----" and "-----END CERTIFICATE-----" (also sometimes represented as .CRT, but double check to be sure.) .cer, .crt - usually in binary DER form (same as .der), but also can be Base64-encoded (like .pem). .P7B - See .p7c .P7C - PKCS#7 SignedData structure without data, just certificate(s) or CRL(s) .PFX - See .p12 .P12 - PKCS#12, may contain certificate(s) (public) and private keys (password protected) 其中,PKCS12是指RSA提出的一種X509文件格式標準。X509還有不少的文件格式標準,好比PEM,不過PKCS12的好處是能夠存儲使用密碼加密保存的私鑰。它用於代替微軟的PFX格式。

PEM實際上DER的BASE64形式,而且在文件頭與文件尾各加上:"-----BEGIN CERTIFICATE-----"和"-----END CERTIFICATE-----"。OpenSSL能夠在這兩種格式之間互轉。OpenSSL在PEM文件裏保存私鑰的時候,文件頭與文件尾分別是:"-----BEGIN RSA PRIVATE KEY-----"和"-----END RSA PRIVATE KEY-----"。


安裝M2Crypto

內容

先決條件 在類Unix系統上安裝,包括Cygwin 在Windows上安裝時的差別 MacOSX的

先決條件 使用 M2Crypto(安裝後)須要如下內容:

Python 2.6,2.7,3.5,或較新的

OpenSSL 1.0.1e 或者更新

要安裝 M2Crypto,您必須可以針對Python和OpenSSL頭文件/庫編譯和連接C源代碼。例如,在基於Debian的系統上,須要如下軟件包:

build-essential

python3-dev 和/或 python-dev

libssl-dev

swig 2.0.4 或者更新(某些人也能夠安裝)

具備swig v1的特殊舊系統。*)

在類Unix系統上安裝,包括Cygwin (未經測試且極可能已過期,歡迎使用Cygwin創建更新信息): $ tar zxf m2crypto-<version>.tar.gz $ cd m2crypto-<version> $ python setup.py build $ python setup.py install 若是你已經安裝了setuptools,你也能夠選擇運行這樣的測試:: $ python setup.py test 這假定安裝了OpenSSL /usr。您可使用--openssl選項爲build_ext(或build)命令提供備用OpenSSL前綴位置 。所以,例如,若是您構建本地版本的OpenSSL並使用/usr/local前綴(您的包含在 /usr/local/include/openssl和libs中/usr/local/lib)安裝它 ,那麼您將添加--openssl=/usr/local到您的build 命令。

在Windows上安裝時的差別 (Windows上再也不支持Python 2.6,若是你想留在Python 2上,只需更新到2.7) (須要更新) 在從源構建以前,您須要安裝OpenSSL的包含文件,導入庫和DLL。OpenSSL 1.1.0及更高版本默認安裝在%ProgramFiles(86)%\OpenSSL(32位)或%ProgramW6432%\OpenSSL(64位)中,或做爲最後的手段,安裝在 %ProgramFiles%\OpenSSL。setup.py將查看這些位置。1.1.0以前的OpenSSL沒有默認安裝位置,所以您必須明確指定其安裝位置。 與其餘平臺同樣,您可使用--openssl選項指定build_ext(或build)命令的OpenSSL位置。例如,--openssl=c:\pkg\openssl將指定能夠c:\pkg\openssl\include在庫中找到OpenSSL包含文件c:\pkg\openssl\lib。 '--openssl'選項將配置swig和編譯器以查找標頭和庫的默認位置。若是您的OpenSSL安裝在一個或者您想修改默認選項,請運行帶有正常distutils選項的build_ext步驟: - swig-opts, - include-dirs, - library-dirs和--libraries。 MSVC ++〜:sub:~ setup.py已配置爲默認使用MSVC ++。 使用MSVC ++,OpenSSL pre 1.1.0 DLL,如構建,命名 libeay32.dll和ssleay32.dll。OpenSSL 1.1.x DLL名稱libcrypto-1_1.dll和libssl-1_1.dll。在你的PATH上安裝這些; 例如c:\bin,與...一塊兒 openssl.exe。 對於MSVC ++中,導入庫,如OpenSSL的預構建1.1.0,被命名爲libeay32.lib和ssleay32.lib。OpenSSL 1.1.x導入庫已命名libcrypto.lib而且libssl.lib。 MINGW :sub:~

注意 如下有關使用MINGW構建M2Crypto的說明來自M2Crypto 0.12。這些說明應繼續適用於此版本,但我還沒有對其進行測試。

閱讀Sebastien Sauvage的網頁: http://sebsauvage.net/python/mingw.html 對於mingw32的,OpenSSL的預1.1.0導入庫命名爲 libeay32.dll.a和libssl32.dll.a。您可能須要編輯這些的setup.py文件。 您還須要建立libpython2[123].a,具體取決於您的Python版本。 OpenSSL的預1.1.0的DLL的mingw32的命名libeay32.dll和 libssl32.dll。OpenSSL 1.1.x DLL名稱libcrypto-1_1.dll 和libssl-1_1.dll。在你的PATH上安裝這些; 例如c:\bin,與...一塊兒openssl.exe。 構建M2Crypto: python setup.py build -cmingw32 python setup.py install BC ++ :sub:~ ~

注意 如下有關使用MSVC ++ 6.0和BC ++ 5.5免費編譯器套件構建M2Crypto的說明來自M2Crypto 0.10。這些說明應繼續適用於此版本,但我還沒有對其進行測試。

注意 OpenSSL 1.1.x不支持BC ++。

對於BC ++,這些文件是使用該工具從MSVC ++建立的coff2omf.exe。我打電話給他們libeay32_bc.lib,並 ssleay32_bc.lib分別。您須要編輯這些的setup.py文件。 您還須要Python的導入庫,例如,python22.lib與BC ++兼容的版本; 即,建立python22_bc.lib從 python22.lib,保存的副本python22.lib(如 python22_vc.lib,說的),而後重命名python22_bc.lib到 python22.lib。 如今您已準備好構建M2Crypto。執行如下操做之一: python setup.py build python setup.py build -cbcpp 而後,: python setup.py install

MacOSX的 Apple沒有提供更新版本的Mac OS X(至少從10.11開始)提供任何版本的OpenSSL,所以有必要使用brew或相似的打包系統來安裝第三方軟件包。Mac OS X用戶建議,這一系列命令在他的系統上爲他提供了M2Crypto的工做副本: $ brew install openssl && brew install swig $ brew --prefix openssl /usr/local/opt/openssl $ LDFLAGS="-L$(brew --prefix openssl)/lib" CFLAGS="-I$(brew --prefix openssl)/include" SWIG_FEATURES="-I$(brew --prefix openssl)/include" pip install m2crypto

相關文章
相關標籤/搜索