模拟一个http 请求的json格式报文,带 rsa 签名操作

一、对需要加密的字符串,定义RsaSignUnsign 类,代码如下:

实现了:

1、实现了生成新的pubkey、pri_key方法;

2、将新生成的keys 写入文件;

3、从文件获取pubkey、pri_key

4、对传入的字符串进行签名,转为bytes类型串,签名,转为base64串,再转为str 串

5、对传入的字符串验签,传入字符串转为bytes串,解base64格式,与原字符串的bytes格式进行验签

 

#coding=utf-8
'''
rsa字符串签名
'''

import rsa
import traceback
import base64

class RsaSignUnsign():
    def __init__(self):
        
        self.pubkey=None
        self.pri_key=None

    def get_newkeys(self,n=1024):
        self.pubkey,self.pri_key=rsa.newkeys(n)
        return self.pubkey,self.pri_key

    def get_keys(self):
        if self.pubkey != None and self.pri_key != None:
            return self.pubkey,self.pri_key
        return None
    
    #如果路径未输入,会在当前路径生成pubkey.pem、pri_key.pem
    def write_keytofile(self,pubkey_path='pubkey.pem',pri_key_path='pri_key.pem'):

        with open(pubkey_path,'w',encoding='utf-8')as fp:
            fp.write(self.pubkey.save_pkcs1().decode('utf-8'))
        
        with open(pri_key_path,'w',encoding='utf-8')as fp:
            fp.write(self.pri_key.save_pkcs1().decode('utf-8'))

    def load_keys(self,pubkey_path='pubkey.pem',pri_key_path='pri_key.pem',encode_format='utf-8'):
        
        try:
            fp=open(pubkey_path,'r',encoding=encode_format)
            fp.readline()

            fp1=open(pri_key_path,'r',encoding=encode_format)
            fp1.readline()
        except:
            traceback.print_exc()
        else:
            fp.seek(0.0)
            self.pubkey=rsa.PublicKey.load_pkcs1(fp.read().encode())
            fp.close()
            fp1.seek(0.0)
            self.pri_key=rsa.PrivateKey.load_pkcs1(fp1.read().encode())
            fp1.close()

        return self.pubkey,self.pri_key

    def rsa_str_sign(self,s_str,sign_type='SHA-1'):
        if not isinstance(s_str,str):
            return None

        s_sign=rsa.sign(s_str.encode('utf-8'),self.pri_key,sign_type)
        s_b64=base64.b64encode(s_sign).decode('utf-8')
        #print('s_b64:',s_b64)

        return s_b64
    
    #s_str 是加密后转码base64 再decode为str类型;s为原str未签名串
    def rsa_str_verify(self,s_str,s):
        if not isinstance(s_str,str):
            return None

        s_b64=s_str.encode('utf-8')
        s_unsign=base64.b64decode(s_b64)

        try:
            result=rsa.verify(s.encode('utf-8'),s_unsign,self.pubkey)
            return result
        except:
            print('验签失败:')
            traceback.print_exc()
  
if __name__=='__main__':
    r=RsaSignUnsign()
    pubkey,prikey=r.get_newkeys(1024)
    #print('pubkey:',pubkey)
    #print('prikey:',prikey)

    r.write_keytofile('e:\\pubkey.pem','e:\\pri_key.pem')

    r.load_keys('e:\\pubkey.pem','e:\\pri_key.pem')
    print(r.get_keys())
    print('*'*30)
    
    s='nihaoma'
    ss=r.rsa_str_sign(s)
    print('ss:',ss)
    
    #s='nihaoma1'
    print('#'*20)
    print(r.rsa_str_verify(ss,s))

二、主程序请求报文,对格式字符串进行拼串,签名操作

 

#coding=utf-8
'''
模拟一个http的json格式请求报文
'''
from rsa_str import *
import json

d_header={'typeCode':'onlineCoupon',
    'version':1.0}
couponUseDateList=["20180228", "20180301", "20180302"]
d_body={'promotionPlanId':10001,
    "faceValue": '%.2f'%5.00,
    "couponUseDateList":couponUseDateList}
signature=''

d={'header':d_header,'body':d_body}

for i in sorted(d_header):
    signature+=str(d_header[i])

for i in sorted(d_body):

    if isinstance(d_body[i],list):
        signature+=''.join(d_body[i])
    else:
        signature+=str(d_body[i])
print('signature:',signature)

rsasign=RsaSignUnsign()
rsasign.load_keys('e:\\pubkey.pem','e:\\pri_key.pem')

signature=rsasign.rsa_str_sign(signature)

d['signature']=signature

d_json=json.dumps(d)

print('d_json:',d_json)

 

posted @ 2019-02-28 15:51  小金儿  阅读(1688)  评论(0编辑  收藏  举报