python實現aes加密解密,RSA簽名和驗籤,RSA加密解密,並呼叫介面
首先公鑰和私鑰如何生成,並且能相容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 -
命令中指明瞭輸入私鑰檔案為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:
-
'''
-
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__
知識點:
除錯程式碼的時候也遇到了一些小問題和技巧
import的時候,如果有同名的類可以起個別名。不然會有報錯,告訴這個類找不到某個方法from Crypto.Cipher import PKCS1_v1_5,from Crypto.Signature import PKCS1_v1_5 as pk,這個需要注意一下
另外,如果想將字典內的單引號都變為雙引號,可以用json.dumps方法
相關推薦
python實現aes加密解密,RSA簽名和驗籤,RSA加密解密,並呼叫介面
用python實現呼叫介面的示例程式碼,過程涉及到很多的加密演算法,值得分享一下。首先公鑰和私鑰如何生成,並且能相容java平臺,嘗試了很多方法。最終決定用openssl命令前提,需要安裝openssl,Crypto庫生成公鑰私鑰對過程:生成私鑰: openssl ge
用Python實現MD5&RSA簽名和驗籤
用pem檔案 pub_key.pem -----BEGIN PUBLIC KEY----- MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQChNn3wKRtPmxaKq2dKsfMn6sO6AKxvtxZgNdh7 HBWq
非對稱加密的簽名和驗籤、加密和解密的Java語言實現
本文采用java.security包的簽名和驗籤。採用A的私鑰簽名傳送至B,B採用A的公鑰進行驗籤。 加解密可以私鑰加密、公鑰解密(或者公鑰加密、私鑰解密)。 一般用於銀行報文傳輸、支付寶、微信、銀行以及各大銀行的資料交換。 package com.example.demo; impo
微信小程式-RSA簽名、驗籤、加密、解密
title: 【小程式】RSA簽名 type: categories date: 2017-05-27 17:01:15 categories: 小程式 tags: [RSA, 簽名] 一個適用於微信小程式的RSA簽名加密庫。 使
Python與Java之間的簽名和驗籤問題
// 最新碰到一個需求, 需要同java下的簽名做驗籤, 感覺有必要總結下: // 整個過程碰到以下幾個問題: /* 1、如何生成指定的公私鑰? # 使用linux指令openssl, openssl這個東西是真的強, (證書問題, 加解密問題, 公私鑰問題等)都
小王的尷尬日常(四)--openssl 實現國密演算法(簽名和驗籤)
昨天呢,更新了加密和解密的實現,今天我們接著來簽名和驗籤。 還是按照王氏慣例先說一下這個理論知識: 下列符號適用於本部分。 A,B:使用公鑰密碼系統的兩個使用者。 a,b: Fq中的元素,它們定義Fq上的一條橢圓曲線E。 2dA:使用
CSP應用開發-簽名和驗籤
下面程式碼實現了呼叫CSP實現資料的簽名和驗籤,函式中有些細節沒有處理好,但總體流程上應該是沒有問題的,測試通過: //本程式通過呼叫CSP實現簽名及驗籤功能 #include "stdafx.h" #include <windows.h> #include
深入淺出數字簽名和驗籤
數字簽名是什麼?1.鮑勃(伺服器)有兩把鑰匙,一把是公鑰,另一把是私鑰。2.鮑勃把公鑰送給他的朋友們----帕蒂(客戶端1)、道格(客戶端2)、蘇珊(客戶端3)----每人一把。3.蘇珊(客戶端3)給鮑勃(伺服器)寫信,寫完後用鮑勃的公鑰加密,達到保密的效果。4.鮑勃收信後,
iOS中使用Openssl X509證書進行字串簽名和驗籤
利用openssl 和x509證書對字串進行簽名和驗籤 //簽名 -(NSString *)rsaSignStringwithString:(NSString *)stringToSign { _signErrorMessage = [[NSStringalloc]ini
Python實現AES加密解密
import base64 from Crypto.Cipher import AES def aes_encrypt(value): ''' >>> aes_en
python 實現AES加密和解密
aes port 加密算 偏移量 blog utf-8 加密和解密 sda return 參考 https://blog.csdn.net/zhchs2012/article/details/79032656 AES加密算法是一種對稱加密算法, 他有一個密匙, 即用來加密,
C#自定義RSA加密解密及RSA簽名和驗證類實例
狀態 share normal evel thumb weight encrypt security clas 本文實例講述了C#自定義RSA加密解密及RSA簽名和驗證類。分享給大家供大家參考。具體分析如下: 這個C#類自定義RSA加密解密及RSA簽名和驗證,包含了RSA
RSA加密、解密、簽名、驗籤的原理及方法
二、RSA加密、簽名區別 加密和簽名都是為了安全性考慮,但略有不同。常有人問加密和簽名是用私鑰還是公鑰?其實都是對加密和簽名的作用有所混淆。簡單的說,加密是為了防止資訊被洩露,而簽名是為了防止資訊被篡改。這裡舉2個例子說明。 第一個場景:戰場上,B要給A傳遞一條訊息,內容為某一指令。 RSA的加密過
Python實現AES加密(對稱加密)
from Cryptodome.Cipher import AES from binascii import b2a_hex,a2b_hex from Cryptodome import Random class AesEncryption(object):
C# RSA加密、解密、加簽、驗籤、支援JAVA格式公鑰私鑰、PEM格式公鑰私鑰、.NET格式公鑰私鑰 -變態模式【支援私鑰加密,公鑰解密】(二)
RSA變態模式:【私鑰加密,公鑰解密】 一般這種寫法都是JAVA弄的。.NET原生不支援。為啥,我也不清楚,大概是因為安全性問題吧,畢竟公鑰是人人都可是持有的。私鑰只有自己擁有。 簽名一直都是【私鑰加簽、公鑰驗籤】只為證明該訊息是你發出來的。 這裡使用了BouncyC
C# RSA加密解密及RSA簽名和驗證
using System; using System.Text; using System.Security.Cryptography; namespace DotNet.Utilities { /// <summary> /// RSA加密解密及R
C# RSA加密、解密、加簽、驗籤、支援JAVA格式公鑰私鑰、PEM格式公鑰私鑰、.NET格式公鑰私鑰、一般模式【支援公鑰加密,私鑰解密】(一)
2017-12-04日更新:增加支援微信支付。程式碼註釋中//☆☆☆☆.NET 4.6以後特有☆☆☆☆的別用,那個不對。 RSA非對稱加密。簡明扼要吧,直說乾貨。(在此特別感謝下貳進位制,提供JAVA版的公鑰私鑰) C#RSA加簽解籤加密比較常見,一般遇到的問題是非.NET
RSA用祕鑰簽名與驗籤 加密解密
一 .下載openssl檔案 匯入二.新建類程式碼如下#import <Foundation/Foundation.h>typedefenum { KeyTypePublic = 0,
【HAVENT原創】前端使用 jsrsasign 進行 RSA 加密、解密、簽名、驗籤
最近因專案需求,需要配合 JAVA 後端返回的簽名,在 H5 網頁中做驗籤功能。網上搜了一下發現了
PYTHON自動化Day6-函式多個返回值和匿名函式、列表生成式,三元運算子,os模組,sys模組,時間模組,字典排序,資料庫操作,加密(md5)
一.函式多個返回值和匿名函式 #函式返回多個值,用一個變數接收 def say(): num1=1 num2=2 num3=3 return num1,num2,num3 res=say() print(res) #打印出來是元組。 函式如果返回多個值的話,會把返回的