python实现rsa加密解密_Python 多种方法实现 RSA 加密/解密,签名/验签

继上篇对 RSA 公钥模数和指数的学习,这次我们针对实际应用中 RSA 加密/解密,签名/验签 的使用,利用 Python 进行具体实现。经过查询整理,发现有三种实现方法,下面我们一一展示。

一、rsa 包的实现

首先需要安装 rsa,pip install rsa

import rsa

import base64

def rsaEncrypt(content, pubkey):

'''

对字符串进行公钥加密

:param content: 被加密的字符串

:return: 加密后的内容

'''

# content = content.encode('utf-8')#明文编码格式

result = rsa.encrypt(content.encode(), pubkey)

return result

def rsaDecrypt(result, privkey):

'''

利用rsa包进行私钥解密

:param result: 被加密的内容

:param privkey: 私钥

:return: 解密后的内容

'''

result = base64.b64decode(result)

print(result)

content = rsa.decrypt(result, privkey).decode()

# content = content.decode('utf-8')

return content

if __name__ == '__main__':

############ 使用公钥 - 私钥对信息进行"加密" + "解密" ##############

message = 'acorn'

#利用rsa包生成公钥、私钥,

(pubkey, privkey) = rsa.newkeys(1024)

print(pubkey, privkey)

print(pubkey.save_pkcs1())

# filename = 'public.pem'

# save(pubkey, filename)

result = rsaEncrypt(message, pubkey)

result = base64.b64encode(result)

print('加密后的密文为:{}'.format(result))

content = rsaDecrypt(result, privkey)

print('解密后的明文为:{}'.format(content))

############ 使用私钥 - 公钥对信息进行"签名" + "验签" ##############

#明文

mss = '重要指令'

#私钥签名

signature = rsa.sign(mss.encode(), privkey, 'SHA-1')

print(signature)

#根据收到的明文、密文,然后用公钥验证,进行身份确认

rsa.verify(mss.encode(), signature, pubkey)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

二、Crypto 包的实现

pycrypto,pycrytodome 和 crypto 是一个东西,crypto 在 python 上面的名字是 pycrypto 它是一个第三方库,但是已经停止更新,所以不建议安装这个库;

windows 下 python3.6 版本以上安装比较麻烦(本人是 Python3.7,尝试安装未成功,如果需要尝试安装的,可以参考点击这里),在安装无果的情况下,可以安装 pycryptodome,它是pycrypto 的延伸版本,用法和 pycrypto 是一模一样的;

pip install pycryptodome1

安装完成后,在 Python 各种引用包存放路径下,把文件夹 crypto 改为 Crypto 即可。

from Crypto.PublicKey import RSA

from Crypto import Random

from Crypto.Cipher import PKCS1_v1_5 #用于加密

import base64

import Crypto.Signature.PKCS1_v1_5 as sign_PKCS1_v1_5 #用于签名/验签

from Crypto import Hash

def generate_rsa_keys():

random_generator = Random.new().read

key = RSA.generate(1024, random_generator) #使用伪随机数来辅助生成

# key = RSA.generate(1024)

pubkey = key.publickey().export_key('PEM') #默认是 PEM的

privkey = key.export_key('PEM')

return pubkey, privkey

def rsaEncrypt(message, pubkey):

'''

RSA加密

:param message: 被加密的字符串

:param pubkey: 公钥

:return:

'''

rsakey = RSA.import_key(pubkey)

cipher = PKCS1_v1_5.new(rsakey)

cipher_text = base64.b64encode(cipher.encrypt(message.encode()))

print(cipher_text)

return cipher_text

def rsaDecrypt(result, privkey):

'''

私钥解密

:param result:

:param privkey:

:return:

'''

result = base64.b64decode(result)

rsakey = RSA.import_key(privkey)

cipher = PKCS1_v1_5.new(rsakey)

content = cipher.decrypt(result, Random.new().read).decode()

print(content)

def save(key, filename):

# 保存密钥

with open(filename, 'w+') as f:

f.write(key)

def read(filename):

# 导入密钥

with open(filename, 'rb') as f:

key = f.read()

return key

def skey_to_pkey(privkey):

'''

已知私钥的情况下,生成公钥

:param privkey:

:return:

'''

s_key = RSA.import_key(privkey)

p_key = s_key.publickey().export_key()

return p_key

def sign_with_privkey(message, privkey):

'''

私钥签名

:param message:明文

:param privkey:

:return:密文

'''

signer = sign_PKCS1_v1_5.new(RSA.import_key(privkey))

rand_hash = Hash.SHA256.new()

rand_hash.update(message.encode())

signature = signer.sign(rand_hash)

return signature

def verify_with_pubkey(signature, message, pubkey):

'''

公钥验签

:param signature:密文

:param message:明文

:param pubkey:公钥

:return:

'''

verifier = sign_PKCS1_v1_5.new(RSA.import_key(pubkey))

rand_hash = Hash.SHA256.new()

rand_hash.update(message.encode())

verify = verifier.verify(rand_hash, signature)

return verify

def execute_without_signature(pubkey, privkey):

'''

公钥加密,私钥解密

:param pubkey:

:param privkey:

:return:

'''

message = 'acorn'

result = rsaEncrypt(message, pubkey)

rsaDecrypt(result, privkey)

print("rsa test success!")

def execute_with_signature(pubkey, privkey):

'''

签名验证,不加密

:param pubkey:

:param privkey:

:return:

'''

text = 'herish'

assert verify_with_pubkey(sign_with_privkey(text,privkey), text, pubkey)

print("rsa Signature verified!")

if __name__ == '__main__':

pubkey, privkey = generate_rsa_keys()

print(pubkey, privkey)

############ 使用公钥 - 私钥对信息进行"加密" + "解密" ##############

execute_without_signature(pubkey, privkey)

############ 使用私钥 - 公钥对信息进行"签名" + "验签" ##############

execute_with_signature(pubkey, privkey)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

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

三、cryptography 包的实现

首先安装 cryptography,pip install cryptography

from cryptography.hazmat.backends import default_backend

from cryptography.hazmat.primitives.asymmetric import rsa,padding

from cryptography.hazmat.primitives import serialization,hashes

from cryptography.hazmat.primitives.serialization import NoEncryption,\

Encoding, PrivateFormat, PublicFormat

import base64

from cryptography.exceptions import InvalidSignature

ALGORITHM_DICT = {

'sha1': hashes.SHA1(),

'sha224': hashes.SHA224(),

'sha256': hashes.SHA256(),

'sha384': hashes.SHA384(),

'sha512': hashes.SHA512()

}

def generate_keys():

'''

生成公钥和私钥

:return:

'''

privkey = rsa.generate_private_key(

public_exponent=65537,

key_size=1024,

backend=default_backend(),

)

new_privkey = privkey.private_bytes(

Encoding.PEM,

PrivateFormat.PKCS8,

NoEncryption()

)

pubkey = privkey.public_key()

new_pubkey = pubkey.public_bytes(

Encoding.PEM,

PublicFormat.SubjectPublicKeyInfo,

)

print(new_pubkey, new_privkey)

return pubkey, privkey

def rsaEncrypt(message, pubkey, algorithm='sha1'):

'''

公钥加密

:param message:

:param pubkey:

:param algorithm:密码散列函数算法

:return:

'''

if not isinstance(message, bytes):

message = message.encode()

algorithm = ALGORITHM_DICT.get(algorithm)

padding_data = padding.OAEP(

mgf=padding.MGF1(algorithm=algorithm),

algorithm=algorithm,

label=None

)

ciphertext = pubkey.encrypt(message, padding_data)

ciphertext = base64.b64encode(ciphertext)

print(ciphertext)

return ciphertext

def rsaDecrypt(result, privkey, algorithm='sha1'):

'''

私钥解密

:param result:加密后的内容

:param privkey:

:param algorithm:密码散列函数算法

:return:

'''

algorithm = ALGORITHM_DICT.get(algorithm)

padding_data = padding.OAEP(

mgf=padding.MGF1(algorithm=algorithm),

algorithm=algorithm,

label=None

)

result = base64.b64decode(result)

content = privkey.decrypt(result, padding_data).decode()

print(content)

return content

def execute_without_signature(pubkey, privkey):

#公钥加密,私钥解密

message = 'herish'

ciphertext = rsaEncrypt(message, pubkey, 'sha256')

content = rsaDecrypt(ciphertext, privkey, 'sha256')

print("rsa test success!")

def sign(message, privkey, algorithm='sha1'):

'''

私钥签名

:param message:

:param privkey:

:param algorithm:

:return:

'''

if not isinstance(message, bytes):

message = message.encode()

algorithm = ALGORITHM_DICT.get(algorithm)

padding_data = padding.PSS(

mgf=padding.MGF1(algorithm),

salt_length=padding.PSS.MAX_LENGTH

)

return privkey.sign(message, padding_data, algorithm)

def verify(message, signature, pubkey, padding_mode='pss', algorithm='sha1'):

'''

公钥验签

:param message:

:param signature:

:param pubkey:

:param padding_mode:

:param algorithm:

:return:

'''

if not isinstance(message, bytes):

message = message.encode()

algorithm = ALGORITHM_DICT.get(algorithm)

if padding_mode == 'pkcs1':

padding_data = padding.PKCS1v15()

else:

padding_data = padding.PSS(

mgf=padding.MGF1(algorithm),

salt_length=padding.PSS.MAX_LENGTH

)

try:

pubkey.verify(signature, message,

padding_data, algorithm)

except InvalidSignature:

padd_verify = False

else:

padd_verify = True

return padd_verify

def execute_with_signature(pubkey, privkey):

text = 'herish'

signature = sign(text, privkey, 'sha256')

assert verify(message=text, signature=signature, pubkey=pubkey, algorithm='sha256')

print("rsa Signature verified!")

if __name__ == '__main__':

pubkey, privkey = generate_keys()

############ 使用公钥 - 私钥对信息进行"加密" + "解密" ##############

# execute_without_signature(pubkey, privkey)

############ 使用私钥 - 公钥对信息进行"签名" + "验签" ##############

execute_with_signature(pubkey, privkey)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

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值