zoukankan      html  css  js  c++  java
  • 23、Python之加密&解密以及加签&验签

    一、rsa基本原理

         关于加密与加签其目的就是为了保证数据传输的安全性,加签的作用就像签名,告诉别人这个就是我发的数据,别人无法模仿,加密的作用是传输的报文是一串密文,他人无法看懂什么意思,下图描述了使用rsa进行加签,加密,验签,解密的过程。

           AB双方生成2对秘钥,A用自己的私钥进行签名(表示是自己发的数据),然后用B的公钥进行加密(这个数据是密文,第三方压根看不懂),B在接收到A发过来的数据时,先用B的私钥进行解密(嘿嘿,只有我能解密),随后用A的公钥进行验签(嗯,就是A发过来的数据),最终使用A传过来的明文进行后续业务处理(上图中B端数据描述不太准确,忽略,懒的画图)。后续通信亦是如此!

    二、python中rsa操作

         python中使用rsa模块,首先我们要先生成2对秘钥值,在python中使用下面代码生成秘钥值(记得生成2对)。

     1 import rsa
     2 
     3 import base64
     4 # 生成密钥
     5 (pubkey, privkey) = rsa.newkeys(1024)
     6 # 保存密钥
     7 with open('public.pem', 'w+') as f:
     8     f.write(pubkey.save_pkcs1().decode())
     9 
    10 with open('private.pem', 'w+') as f:
    11     f.write(privkey.save_pkcs1().decode())
    View Code

    生成的2对秘钥如下:

     1 import rsa,json
     2 import base64
     3 def encrypt_data(message):
     4     data = {}
     5     data['message'] = message
     6     print("明文:%s" % data)
     7     #用A的私钥加签
     8     str_data = json.dumps(data)
     9     with open('a_private.pem', 'r') as f:
    10         privkey = rsa.PrivateKey.load_pkcs1(f.read().encode())
    11         signature = rsa.sign(str_data.encode('utf-8'), privkey, 'SHA-1')
    12         sign = base64.b64encode(signature)
    13         data['sign'] = sign.decode()
    14     str_data = json.dumps(data)
    15 
    16     #用B的公钥加密
    17     finally_data = {}
    18     PAGE_SIZE = 110  # 每页大小 因为加密最大长度为117 需要进行切片加密
    19     data_lengh = len(str_data) - 1
    20     pages = data_lengh // PAGE_SIZE if (data_lengh % PAGE_SIZE) == 0 else data_lengh // PAGE_SIZE + 1
    21     with open('b_public.pem', 'r') as f:
    22         pubkey = rsa.PublicKey.load_pkcs1(f.read().encode())
    23     for page in range(pages):
    24         if page < pages - 1:
    25             value = str_data[PAGE_SIZE * page:PAGE_SIZE * (page + 1)]
    26         else:
    27             value = str_data[PAGE_SIZE * page:]
    28         encrypt_data = rsa.encrypt(value.encode('utf-8'),pubkey)
    29         finally_data[page] = base64.b64encode(encrypt_data).decode()
    30 
    31     print("加签后的密文:" , finally_data)
    32     return finally_data
    33 
    34 def decry_data(encrypt_message):
    35     #B的私钥解密
    36     with open('b_private.pem', 'r') as f:
    37         privkey = rsa.PrivateKey.load_pkcs1(f.read().encode())
    38     final_data = ''
    39     for index in encrypt_message:
    40         temp_data = base64.b64decode(encrypt_message[index])
    41         data = rsa.decrypt(temp_data,privkey).decode()
    42         final_data = final_data + data
    43     print("解密后的明文:%s" % final_data)
    44     #A的公钥验签
    45     with open('a_public.pem', 'r') as f:
    46         pubkey = rsa.PublicKey.load_pkcs1(f.read().encode())
    47     message  = {}
    48     final_data = json.loads(final_data)
    49     message['message'] = final_data['message']
    50     sign = base64.b64decode(final_data['sign'])
    51     message_str = json.dumps(message)
    52     result = rsa.verify(message_str.encode("utf-8"), sign, pubkey)
    53     print("明文:%s,验签结果:%s" % (message_str,result))
    54 data = encrypt_data("hi,I am A")
    55 decry_data(data)
    View Code

    上面的代码即实现了上图的通信,下面描述一下整个过程:

     A端要发送的数据是:data=['message'] = 'hi,I am A'。于是A开始进行安全性操作,

            第一步:用a自己的私钥进行加签,获得签名值sign,之后又用base64做了一个编码,然后将签到值存放在data中。

            第二步,进行加密,由于rsa只能支持117位的数据的加密,因此需要对进行加密的数据进行切割再加密,对切割的每段进行加密之后再使用base64进行编码最终将加密后的数据发送出去。

    B端接收数据:

            第一步,对每段加密的报文进行base64解码,然后再进行rsa解密。

            第二步,拿到解密后的报文,其中包含A传输过来的明文和签名值,对签名值进行base64进行解码,然后对A发送过来的数据进行验签,一切顺利后,即认为报文的是正确的且安全性的。

    注解:在这个过程中存在很多编码的问题,应当小心。

  • 相关阅读:
    智能车回忆
    自动化面试问题
    先进控制理论(转载)
    电力电子技术(转载)
    微型计算机原理及应用复习(转载)
    c语言中数值交换用值传递和地址传递
    unity调用苹果端方法
    unity调用安卓arr方法
    unity mono单例
    loading通用界面笔记
  • 原文地址:https://www.cnblogs.com/win0211/p/8671588.html
Copyright © 2011-2022 走看看