python调用接口参数加密_python实现aes加密解密,RSA签名和验签,RSA加密解密,并调用接口...

#!-*- coding:utf-8 -*-

'''

Created on 2013-5-24

@author: shangwei

'''

from Crypto import Random

from Crypto.Cipher import PKCS1_v1_5

from Crypto.Hash import SHA

from hashlib import sha1

from rsa import key, common, encrypt

from urllib import urlencode

import base64

import hmac

from Crypto.PublicKey import RSA

import urllib

import urllib2

import time

import json

from Crypto.Signature import PKCS1_v1_5 as pk

import Gl

class MerchantAPI:

def doPost(self,url,values):

'''

post请求

参数URL

字典类型的参数

'''

req = urllib2.Request(url)

data = urllib.urlencode(values)

res = urllib2.urlopen(req, data)

ret = res.read()

return ret

def doGet(self,url,values):

'''

get请求

参数URL

字典类型的参数

'''

REQUEST = url + "?" + urllib.urlencode(values)

ret = urllib2.urlopen(REQUEST).read()

return ret

@staticmethod

def _pkcs7padding(data):

"""

对齐块

size 16

999999999=>9999999997777777

"""

size = AES.block_size

count = size - len(data)%size

if count:

data+=(chr(count)*count)

return data

@staticmethod

def _depkcs7padding(data):

"""

反对齐

"""

newdata = ''

for c in data:

if ord(c) > AES.block_size:

newdata+=c

return newdata

'''

aes加密base64编码

'''

def aes_base64_encrypt(self,data,key):

"""

@summary:

1. pkcs7padding

2. aes encrypt

3. base64 encrypt

@return:

string

"""

cipher = AES.new(key)

return base64.b64encode(cipher.encrypt(self._pkcs7padding(data)))

def base64_aes_decrypt(self,data,key):

"""

1. base64 decode

2. aes decode

3. dpkcs7padding

"""

cipher = AES.new(key)

return self._depkcs7padding(cipher.decrypt(base64.b64decode(data)))

'''

rsa加密

'''

def rsa_base64_encrypt(self,data,key):

'''

1. rsa encrypt

2. base64 encrypt

'''

cipher = PKCS1_v1_5.new(key)

return base64.b64encode(cipher.encrypt(data))

'''

rsa解密

'''

def rsa_base64_decrypt(self,data,key):

'''

1. base64 decrypt

2. rsa decrypt

示例代码

key = RSA.importKey(open('privkey.der').read())

>>>

>>> dsize = SHA.digest_size

>>> sentinel = Random.new().read(15+dsize) # Let's assume that average data length is 15

>>>

>>> cipher = PKCS1_v1_5.new(key)

>>> message = cipher.decrypt(ciphertext, sentinel)

>>>

>>> digest = SHA.new(message[:-dsize]).digest()

>>> if digest==message[-dsize:]: # Note how we DO NOT look for the sentinel

>>> print "Encryption was correct."

>>> else:

>>> print "Encryption was not correct."

'''

cipher = PKCS1_v1_5.new(key)

return cipher.decrypt(base64.b64decode(data), Random.new().read(15+SHA.digest_size))

'''

RSA签名

'''

def sign(self,signdata):

'''

@param signdata: 需要签名的字符串

'''

h=SHA.new(signdata)

signer = pk.new(Gl.privatekey)

signn=signer.sign(h)

signn=base64.b64encode(signn)

return signn

'''

RSA验签

结果:如果验签通过,则返回The signature is authentic

如果验签不通过,则返回"The signature is not authentic."

'''

def checksign(self,rdata):

signn=base64.b64decode(rdata.pop('sign'))

signdata=self.sort(rdata)

verifier = pk.new(Gl.publickey)

if verifier.verify(SHA.new(signdata), signn):

print "The signature is authentic."

else:

print "The signature is not authentic."

def sort(self,mes):

'''

作用类似与java的treemap,

取出key值,按照字母排序后将value拼接起来

返回字符串

'''

_par = []

keys=mes.keys()

keys.sort()

for v in keys:

_par.append(str(mes[v]))

sep=''

message=sep.join(_par)

return message

'''

请求接口前的加密过程

'''

def requestprocess(self,mesdata):

'''

加密过程:

1、将需要的参数mes取出key排序后取出value拼成字符串signdata

2、用signdata对商户私钥进行rsa签名,生成签名signn,并转base64格式

3、将签名signn插入到mesdata的最后生成新的data

4、用encryptkey16位常量对data进行AES加密后转BASE64,生成机密后的data

5、用对方公钥publickey对encryptkey16位常量进行RSA加密BASE64编码,生成加密后的encryptkey

'''

signdata=self.sort(mesdata)

print '需要签名的排序后的字符串为:'+signdata

signn=self.sign(signdata)

mesdata['sign']=signn

print mesdata

encryptkey = '1234567890123456'

data=self.aes_base64_encrypt(json.dumps(mesdata),encryptkey)

print '加密后的data='+data

values={}

values['merchantaccount']=Gl.merchantaccount

values['data']=data

values['encryptkey']=self.rsa_base64_encrypt(encryptkey,Gl.publickey)

return values

'''

对返回结果进行解密后输出

'''

def result_decrypt(self,result):

'''

1、返回的结果json传给data和encryptkey两部分,都为加密后的

2、用商户私钥对encryptkey进行RSA解密,生成解密后的encryptkey。参考方法:rsa_base64_decrypt

3、用解密后的encryptkey对data进行AES解密。参考方法:base64_aes_decrypt

'''

result=json.loads(result)

kdata=result['data']

kencryptkey=result['encryptkey']

print '返回的加密后的data='+kdata

print '返回的加密后的encryptkey='+kencryptkey

cryptkey=self.rsa_base64_decrypt(kencryptkey,Gl.privatekey)

print '解密后的encryptkey='+cryptkey

rdata=self.base64_aes_decrypt(kdata,cryptkey)

print '解密后的data='+rdata

return rdata

def testCreditPayAsync(self):

'''

生成公钥私钥对过程:

生成私钥:openssl genrsa -out rsa_private_key.pem 1024

根据私钥生成公钥: openssl rsa -in rsa_private_key.pem -out rsa_public_key.pem -pubout

这时候的私钥还不能直接被使用,需要进行PKCS#8编码:

openssl pkcs8 -topk8 -in rsa_private_key.pem -out pkcs8_rsa_private_key.pem -nocrypt

命令中指明了输入私钥文件为rsa_private_key.pem,输出私钥文件为pkcs8_rsa_private_key.pem,不采用任何二次加密(-nocrypt)

加密过程:

1、将需要的参数mes取出key排序后取出value拼成字符串signdata

2、用signdata对商户私钥进行rsa签名,生成签名signn,并转base64格式

3、将签名signn插入到mes的最后生成新的data

4、用encryptkey16位常量对data进行AES加密后转BASE64,生成机密后的data

5、用对方公钥publickey对encryptkey16位常量进行RSA加密BASE64编码,生成加密后的encryptkey

6、将merchantaccount,第四部加密后的data,第五步加密后的encryptkey作为参数post请求给URL http://xxxx/xxx/api/xxx/xxx/xxx/xxx

7、返回的结果json传给data和encryptkey两部分,都为加密后的

8、用商户私钥对encryptkey进行RSA解密,生成解密后的encryptkey。参考方法:rsa_base64_decrypt

9、用解密后的encryptkey对data进行AES解密。参考方法:base64_aes_decrypt

'''

transtime=int(time.time())

od=str(random.randint(10, 100000))

mesdata={"merchantaccount":Gl.merchantaccount,"cardno":"xxxx758xxxx23xxxx","validthru":"04xx","cvv2":"200","phone":"1581xxxxxxx",

"orderid":"33hhkssseef3u"+od,"transtime":transtime,"currency":156,"amount":2,"productcatalog":"1","productname":"","productdesc":"",

"userip":"192.168.5.251","identityid":"ee","identitytype":6,"other":"","callbackurl":"http://IP/webtest/callback.do"}

values=self.requestprocess(mesdata)

url='http://'+Gl.URL+'/xxxx'

print url

result=self.doPost(url, values)

print result

rdata=json.loads(self.result_decrypt(result))

self.checksign(rdata)

if __name__=='__main__

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值