python模块app登陆认证(M2Crypto数字证书加密)

需求:

1、通过数字证书,非对称加密方式传送对称秘钥给服务端

2、用户名、密码使用对称秘钥加密,发送服务端验证

3、传送数据使用字节流方式

 

实现思路:

1、了解python的struct模块,用于字节流组件

2、安装M2Crypto模块,此模块依赖第三方软件swig、openssl

 

M2Crypto模块安装步骤(centos6.5环境)

1、安装python2.7.10
yum -y install openssl openssl-devel ncurses-devel.x86_64  bzip2-devel sqlite-devel python-devel zlib libcurl-devel mysql-devel libpcap-devel
tar zxvf Python-2.7.10.tgz
mkdir -p /usr/local/python/2.7.10/lib
./configure --enable-shared --prefix=/usr/local/python/2.7.10 LDFLAGS="-Wl,-rpath /usr/local/python/2.7.10/lib"
make
make install
mv /usr/bin/python /usr/bin/python2.6.6
ln -fs /usr/local/python/2.7.10/bin/python2.7 /usr/bin/python

2、配置yum调用python版本
vi /usr/bin/yum
 修改成!/usr/bin/python2.6.6
安装 setuptools、pip

3、配置环境变量
export PATH=/usr/local/swig3.0.7/bin:$PATH:/usr/local/python/2.7.10/bin:/usr/local/pcre/bin
export LD_LIBRARY_PATH=/lib:/usr/local/pcre/lib/

4、安装PCRE
下载地址:http://www.pcre.org/
./configure --prefix=/usr/local/pcre
make
make install
ln -s /usr/local/pcre/lib/libpcre.so.1 /lib

或者yum安装

yum install -y pcre pcre-devel


5、安装swig
下载地址:http://www.swig.org/download.html
./configure --prefix=/usr/local/swig3.0.7
make
make install

查看版本信息swig -version,如果版本信息与安装的不匹配,which swig,看下当前swig程序的路径,如果不是自己安装的路径,修改环境变量。

6、安装M2Crypto
下载地址:https://pypi.python.org/pypi/M2Crypto/0.22.5
cp /usr/include/openssl/opensslconf-x86_64.h ./
python setup.py install

 

 

M2Crypto模块安装步骤(Ubuntu 16.04.1环境)

1、基础安装

apt-get install g++ build-essential make

2、安装python2.7

apt-get install python2.7

3、安装pcre

apt-get install libpcre3 libpcre3-dev

4、安装swig

下载地址 http://www.swig.org/download.html
./configure --prefix=/usr/local/swig3.0.7
make
make install
配置环境变量
vi /root/.bashrc
export PATH=/usr/local/swig3.0.7/bin:$PATH

5、安装M2Crypto
apt-get install python-m2crypto

 

struc模块说明

struct模块中最重要的三个函数是pack(), unpack(), calcsize()
pack(fmt, v1, v2, ...)   按照给定的格式(fmt),把数据封装成字符串(实际上是类似于c结构体的字节流)
unpack(fmt, string)      按照给定的格式(fmt)解析字节流string,返回解析出来的tuple
calcsize(fmt)            计算给定的格式(fmt)占用多少字节的内存

struct中支持的格式如下表:

Format

C Type

Python

字节数

x

pad byte

no value

1

c

char

string of length 1

1

b

signed char

integer

1

B

unsigned char

integer

1

?

_Bool

bool

1

h

short

integer

2

H

unsigned short

integer

2

i

int

integer

4

I

unsigned int

integer or long

4

l

long

integer

4

L

unsigned long

long

4

q

long long

long

8

Q

unsigned long long

long

8

f

float

float

4

d

double

float

8

s

char[]

string

1

p

char[]

string

1

P

void *

long

 

 

注1.q和Q只在机器支持64位操作时有意思

注2.每个格式前可以有一个数字,表示个数

注3.s格式表示一定长度的字符串,4s表示长度为4的字符串,但是p表示的是pascal字符串

注4.P用来转换一个指针,其长度和机器字长相关

注5.最后一个可以用来表示指针类型的,占4个字节

 

为了同c中的结构体交换数据,还要考虑有的cc++编译器使用了字节对齐,通常是以4个字节为单位的32位系统,故而struct根据本地机器字节顺序转换.可以用格式中的第一个字符来改变对齐方式.定义如下:

Character

Byte order

Size and alignment

@

native

native            凑够4个字节

=

native

standard        按原字节数

< 

little-endian

standard        按原字节数

> 

big-endian

standard       按原字节数

!

network (= big-endian)

standard       按原字节数

使用方法是放在fmt的第一个位置,就像'@5s6sif'

 

数字证书加密代码

 1 from M2Crypto import X509, EVP, RSA, ASN1, BIO
 2 
 3 def random_key():
 4     # 随机秘钥(8位)
 5     checkcode = ''
 6     for i in range(8):
 7         current = random.randrange(0, 8)
 8         if current != i:
 9             temp = chr(random.randint(65, 90))
10         else:
11             temp = random.randint(0, 9)
12         checkcode += str(temp)
13     return checkcode
14 
15 key = random_key()
16 encrypted_key = RSA.load_pub_key("rsa_public.key")
17 encrypted = encrypted_key.public_encrypt(key, RSA.pkcs1_padding)
View Code

M2Crypto使用 http://www.heikkitoivonen.net/m2crypto/api/

字节流组包代码

 1 def header(body,datasize,isprocess,processsize,msgId):
 2     #结构体包头
 3     #ZipHeader
 4     datasize_len = datasize
 5     isprocess_num = isprocess
 6     processsize_len = processsize
 7     datasize = struct.pack('i', datasize_len)
 8     isprocess = struct.pack('h', isprocess_num)
 9     processsize = struct.pack('i', processsize_len)
10     ZipHeader = datasize+isprocess+processsize+body
11 
12     #RequestHeader
13     pkgSize_len = len(ZipHeader)
14     msgId = msgId
15     ownerId = 0
16     magicId = 0
17     RequestHeader = struct.pack('3Ih%ds' % pkgSize_len, pkgSize_len, msgId, ownerId, magicId, ZipHeader)
18     return RequestHeader
View Code

 

字节流参考博客:http://blog.csdn.net/jrckkyy/article/details/38816565

 

posted @ 2016-01-07 16:58  shhnwangjian  阅读(2489)  评论(0编辑  收藏  举报