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中支持的格式如下表:
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中的结构体交换数据,还要考虑有的c或c++编译器使用了字节对齐,通常是以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)
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
字节流参考博客:http://blog.csdn.net/jrckkyy/article/details/38816565