模块_使用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

相关文章
相关标签/搜索