一、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())
生成的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)
上面的代码即实现了上图的通信,下面描述一下整个过程:
A端要发送的数据是:data=['message'] = 'hi,I am A'。于是A开始进行安全性操作,
第一步:用a自己的私钥进行加签,获得签名值sign,之后又用base64做了一个编码,然后将签到值存放在data中。
第二步,进行加密,由于rsa只能支持117位的数据的加密,因此需要对进行加密的数据进行切割再加密,对切割的每段进行加密之后再使用base64进行编码最终将加密后的数据发送出去。
B端接收数据:
第一步,对每段加密的报文进行base64解码,然后再进行rsa解密。
第二步,拿到解密后的报文,其中包含A传输过来的明文和签名值,对签名值进行base64进行解码,然后对A发送过来的数据进行验签,一切顺利后,即认为报文的是正确的且安全性的。
注解:在这个过程中存在很多编码的问题,应当小心。
来源:oschina
链接:https://my.oschina.net/u/4388720/blog/4028020