您的位置:首页 > 编程语言 > Python开发

RSA加密的实现(Python2.7(分段加密)+python3)

2018-01-17 15:54 716 查看

转载自:http://blog.csdn.net/qq_33414271


什么是RSA加密呢?

RSA是一种非对称加密算法,那什么是非对称加密呢?非对称加密又叫做公开密钥加密,就是说我有一对密钥,分为公钥和私钥。私钥我悄悄的留着,不给别人看。然后把公钥给别人(无论是谁)。当别人用公钥加密了数据之后,这串加密后的数据只有我(拥有私钥的人)用私钥才能解开,其余谁都不能解开。这就是非对称加密。

加密时遇到的问题: 

加密的 plaintext 最大长度是 证书key位数/8 - 11, 例如1024 bit的证书,被加密的串最长 1024/8 - 11=117

那么加密长的文本就需要分段进行加密


python2的实现

def rsa_long_encrypt(pub_key_str, msg)为加密方法,要求输入公钥和明文

def rsa_long_decrypt(priv_key_str, msg)为解密方法,要求输入私钥和密文
#coding:utf-8
import sys

reload(sys)
sys.setdefaultencoding('utf8')

from Crypto.PublicKey import RSA as rsa
from Crypto.Cipher import PKCS1_v1_5 #RSA加密协议

#公密钥对在线生成(1024bit)
pub_key_str = """-----BEGIN RSA PUBLIC KEY-----
MIIBCgKCAQEAuw4T755fepEyXTM66pzf6nv8NtnukQTMGnhmBFIFHp/P2vEpxjXU
BBDUpzKkVFR3wuK9O1FNmRDAGNGYC0N/9cZNdhykA1NixJfKQzncN31VJTmNqJNZ
W0x7H9ZGoh2aE0zCCZpRlC1Rf5rL0SVlBoQkn/n9LnYFwyLLIK5/d/y/NZVL6Z6L
cyvga0zRajamLIjY0Dy/8YIwVV6kaSsHeRv2cOB03eam6gbhLGIz/l8wuJhIn1rO
yJLQ36IOJymbbNmcC7+2hEQJP40qLvH7hZ1LaAkgQUHjfi8RvH2T1Jmce7XGPxCo
Ed0yfeFz+pL1KeSWNey6cL3N5hJZE8EntQIDAQAB
-----END RSA PUBLIC KEY-----"""

priv_key_str = """-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAuw4T755fepEyXTM66pzf6nv8NtnukQTMGnhmBFIFHp/P2vEp
xjXUBBDUpzKkVFR3wuK9O1FNmRDAGNGYC0N/9cZNdhykA1NixJfKQzncN31VJTmN
qJNZW0x7H9ZGoh2aE0zCCZpRlC1Rf5rL0SVlBoQkn/n9LnYFwyLLIK5/d/y/NZVL
6Z6Lcyvga0zRajamLIjY0Dy/8YIwVV6kaSsHeRv2cOB03eam6gbhLGIz/l8wuJhI
n1rOyJLQ36IOJymbbNmcC7+2hEQJP40qLvH7hZ1LaAkgQUHjfi8RvH2T1Jmce7XG
PxCoEd0yfeFz+pL1KeSWNey6cL3N5hJZE8EntQIDAQABAoIBAGim1ayIFK8EMQNH
uDyui/Aqcc9WWky0PGTK23irUsXxb1708gQ89WNY70Cj6qBrqZ1VMb3QHPP4FSFN
kh0rJJoi2g+ssm5R5r5KlhTKeFRrQInVC1Y3KhUUUwZa4aWtnhgSJ7Urq1yVhjU4
K7PVkhH1OHBwcp/d1Bd6jd65AgPkY63P+WpcARJkClmQ1RhgoRwThyJdpKrV4/gO
ha0AUGlJNRNvRwiZxP0zaI5C8RdrG96SnVpeYOcD0z/M1HVlkoYMXsXLKttwLfpK
88Igtm6ZJwRpfuMF5VA+9hHaYGCBdGz0B/rMp2fc+EtrOavYQGrWIWi2RL1Qk6Rt
BUyeTgECgYEA9anj4n/cak1MT+hbNFsL31mJXryl1eVNjEZj/iPMztpdS15CmFgj
Kjr9UuintjSiK7Is43nZUWWyP1XQjRhVi2uP7PRIv92QNl/YteWD6tYCInJHKe2J
QqYyZrElezsdayXb5DK6bi1UIYYji90g79N7x6pOR0UnQNQUXTv+Y8ECgYEAwuzl
6Ez4BSXIIL9NK41jfNMa73Utfl5oO1f6mHM2KbILqaFE76PSgEeXDbOKdcjCbbqC
KCGjwyPd+Clehg4vkYXTq1y2SQGHwfz7DilPSOxhPY9ND7lGbeNzDUK4x8xe52hd
MWKdgqeqCK83e5D0ihzRiMah8dbxmlfLAOZ3sPUCgYEA0dT9Czg/YqUHq7FCReQG
rg3iYgMsexjTNh/hxO97PqwRyBCJPWr7DlU4j5qdteobIsubv+kSEI6Ww7Ze3kWM
u/tyAeleQlPTnD4d8rBKD0ogpJ+L3WpBNaaToldpNmr149GAktgpmXYqSEA1GIAW
ZAL11UPIfOO6dYswobpevYECgYEApSosSODnCx2PbMgL8IpWMU+DNEF6sef2s8oB
aam9zCi0HyCqE9AhLlb61D48ZT8eF/IAFVcjttauX3dWQ4rDna/iwgHF5yhnyuS8
KayxJJ4+avYAmwEnfzdJpoPRpGI0TCovRQhFZI8C0Wb+QTJ7Mofmt9lvIUc64sff
GD0wT/0CgYASMf708dmc5Bpzcis++EgMJVb0q+ORmWzSai1NB4bf3LsNS6suWNNU
zj/JGtMaGvQo5vzGU4exNkhpQo8yUU5YbHlA8RCj7SYkmP78kCewEqxlx7dbcuj2
LAPWpiDca8StTfEphoKEVfCPHaUk0MlBHR4lCrnAkEtz23vhZKWhFw==
-----END RSA PRIVATE KEY-----"""

#单次加密串的长度最大为 (key_size/8)-11

'''
加密的 plaintext 最大长度是 证书key位数/8 - 11, 例如1024 bit的证书,被加密的串最长 1024/8 - 11=117,
解决办法是 分块 加密,然后分块解密就行了,
因为 证书key固定的情况下,加密出来的串长度是固定的。
'''
def rsa_long_encrypt(pub_key_str, msg):
msg = msg.encode('utf-8')
length = len(msg)
default_length = 117
#公钥加密
pubobj = PKCS1_v1_5.new(rsa.importKey(pub_key_str))
#长度不用分段
if length < default_length:
return "".join(pubobj.encrypt(msg))
#需要分段
offset = 0
res = []
while length - offset > 0:
if length - offset > default_length:
res.append(pubobj.encrypt(msg[offset:offset+default_length]))
else:
res.append(pubobj.encrypt(msg[offset:]))
offset += default_length
return "".join(res)

def rsa_long_decrypt(priv_key_str, msg):
#msg = msg.encode('utf-8')
length = len(msg)
default_length = 256
#私钥解密
priobj = PKCS1_v1_5.new(rsa.importKey(priv_key_str))
#长度不用分段
if length < default_length:
return "".join(priobj.decrypt(msg,'xyz'))
#需要分段
offset = 0
res = []
while length - offset > 0:
if length - offset > default_length:
res.append(pr
e4a4
iobj.decrypt(msg[offset:offset+default_length],'xyz'))
else:
res.append(priobj.decrypt(msg[offset:],'xyz'))
offset += default_length
return "".join(res)

#明文
msg = "H134"*1000

e = rsa_long_encrypt(pub_key_str, msg)
d = rsa_long_decrypt(priv_key_str, e)
print "加密后是:%s ;   解密后是:%s  "%(e ,d)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102

PyCrypto 可能是 Python 中密码学方面最有名的第三方软件包。可惜的是,它的开发工作于2012年就已停止。幸运的是,有一个该项目的分支取代了 PyCrypto ,那就是 PyCrytodome。

windows下的安装命令
pip install pycryptodomex
1


python3的RSA加密实现

def create_rsa_key(self,password)为生成公钥和私钥的方法,其中私钥和password相关联,也就是将本地的私钥存储起来,可以用密码+私钥的方式解码,而不需要记忆复杂私钥。
'''
RSA算法
'''

from Cryptodome.PublicKey import RSA
from Cryptodome.Cipher import PKCS1_OAEP, PKCS1_v1_5

class MyRSA():

def create_rsa_key(self,password):
"""
创建RSA密钥
步骤说明:
1、从 Crypto.PublicKey 包中导入 RSA,创建一个密码
2、生成 1024/2048 位的 RSA 密钥
3、调用 RSA 密钥实例的 exportKey 方法,传入密码、使用的 PKCS 标准以及加密方案这三个参数。
4、将私钥写入磁盘的文件。
5、使用方法链调用 publickey 和 exportKey 方法生成公钥,写入磁盘上的文件。
"""

key = RSA.generate(1024)
encrypted_key = key.exportKey(passphrase=password.encode("utf-8"), pkcs=8,
protection="scryptAndAES128-CBC")
with open("my_private_rsa_key.bin", "wb") as f:
f.write(encrypted_key)
with open("my_rsa_public.pem", "wb") as f:
f.write(key.publickey().exportKey())

def encrypt(self,plaintext):
# 加载公钥
recipient_key = RSA.import_key(
open("my_rsa_public.pem").read()
)
cipher_rsa = PKCS1_v1_5.new(recipient_key)

en_data = cipher_rsa.encrypt(plaintext.encode("utf-8"))

return en_data
#print(len(en_data), en_data)
def decrypt(self,en_data,password):
# 读取密钥
private_key = RSA.import_key(
open("my_private_rsa_key.bin").read(),
passphrase=password
)
cipher_rsa = PKCS1_v1_5.new(private_key)
data = cipher_rsa.decrypt(en_data, None)

return data
#print(data)

mrsa=MyRSA()
mrsa.create_rsa_key('123456')
e=mrsa.encrypt('hello')
d=mrsa.decrypt(e,'123456')
print(e)
print(d)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60

其中create_rsa_key为创建公钥密钥,encrypt为加密,decrypt为解密

参考文献 
https://zhuanlan.zhihu.com/p/26595398 
http://blog.csdn.net/yannanxiu/article/details/76436032
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: