python實現aes加密解密,RSA簽名和驗籤,RSA加密解密,並呼叫介面
文章來自:http://blog.csdn.net/kevin6216/article/details/7573753
用python實現呼叫介面的示例程式碼,過程涉及到很多的加密演算法,值得分享一下。
首先公鑰和私鑰如何生成,並且能相容java平臺,嘗試了很多方法。最終決定用openssl命令
前提,需要安裝openssl,Crypto庫
生成公鑰私鑰對過程:
生成私鑰:
- openssl genrsa -out rsa_private_key.pem 1024
- openssl rsa -in rsa_private_key.pem -out rsa_public_key.pem -pubout
- 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)
這時候就獲得了一對公鑰和私鑰,只要拿到對方的公鑰,用自己的公鑰的格式替換就可以使用啦~~
我們最好把全域性變數給提出來,便於管理。這樣子就不用改程式碼都改一遍了
檔案Gl.py
-
#!-*- coding:utf-8 -*-
-
'''
-
Created on 2013-6-15
-
-
@author: shangwei
-
'''
-
'''
-
全域性變數
-
'''
-
from Crypto.PublicKey import RSA
-
'''
-
publickey為對方的公鑰
-
privatekey為商戶自己的私鑰
-
'''
-
publickey = RSA.importKey(open('rsa_public_key.pem','r').read())
-
privatekey=RSA.importKey(open('pkcs8_rsa_private_key.pem','r').read())
-
merchantaccount='YB010000000xx'
- URL='xxx.xxx.com'
-
#!-*- 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":""}
-
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__
知識點:
除錯程式碼的時候也遇到了一些小問題和技巧
import的時候,如果有同名的類可以起個別名。不然會有報錯,告訴這個類找不到某個方法from Crypto.Cipher import PKCS1_v1_5,from Crypto.Signature import PKCS1_v1_5 as pk,這個需要注意一下
另外,如果想將字典內的單引號都變為雙引號,可以用json.dumps方法
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/26250550/viewspace-1284723/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 在VUE中使用RSA加密解密加簽解籤Vue加密解密
- RSA加密與解密加密解密
- python加密與解密,加簽與驗籤Python加密解密
- php rsa長文加密解密PHP加密解密
- RSA 非對稱加密&解密加密解密
- RSA加密解密示例程式碼加密解密
- RSA der加密 p12解密以及配合AES使用詳解加密解密
- AES加密解密加密解密
- AES 加密&解密加密解密
- Python AES 加密和解密(qbit)Python加密解密
- python AES-CBC 加密解密Python加密解密
- AES CBC 加密解密加密解密
- php中aes加密和rsa加密的區別PHP加密
- RSA加密解密原理深度剖析(附CTF中RSA題型實戰分析)加密解密
- 【5】JMicro其於RSA及AES加密實現安全服務呼叫加密
- nodejs常用加密方式 RSA & AESNodeJS加密
- RSA加密解密(無資料大小限制,php、go、java互通實現)加密解密PHPGoJava
- iOS端基於RSA公鑰加密和解密iOS加密解密
- 安全篇-AES/RSA加密機制加密
- app直播原始碼,android AES加密解密實現APP原始碼Android加密解密
- 通過Go實現AES加密和解密工具Go加密解密
- 非對稱加密中,加解密和簽名加密解密
- security.js RSA加密與java客戶端解密JS加密Java客戶端解密
- Java RSA (SHA1withRSA)簽名和驗籤Java
- golang AES-CBC 加密解密Golang加密解密
- java/php/c#版rsa簽名以及java驗籤實現JavaPHPC#
- java RSA 解密Java解密
- Java AES加密和解密教程 - BaeldungJava加密解密
- Python使用AES進行鹽值加密和解密Python加密解密
- 安全基礎:數字信封、數字簽名、數字證書(加簽驗籤,加密解密)加密解密
- AES實現財務資料的加密解密儲存加密解密
- C#通過java生成的RSA公鑰加密和解密C#Java加密解密
- RSA 非對稱加密&解密,超長字串分塊處理加密解密字串
- RSA加密加密
- 前後端java+vue 實現rsa 加解密與摘要簽名演算法後端JavaVue解密演算法
- AES位元組陣列加密解密流程陣列加密解密
- delphi加密C#解密(AES-256)加密C#解密
- C# Rsa加密(私鑰加密、公鑰解密、金鑰格式轉換、支援超大長度分段加密)C#加密解密
- JavaScript前端和Java後端的AES加密和解密JavaScript前端後端加密解密