日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > python >内容正文

python

python RSA加密、解密、签名

發(fā)布時(shí)間:2025/3/11 python 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python RSA加密、解密、签名 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

python中用于RSA加解密的庫(kù)有好久個(gè),本文主要講解rsa、M2Crypto、Crypto這三個(gè)庫(kù)對(duì)于RSA加密、解密、簽名、驗(yàn)簽的知識(shí)點(diǎn)。

知識(shí)基礎(chǔ)

加密是為了保證傳輸內(nèi)容隱私,簽名是為了保證消息真實(shí)性。

服務(wù)器存私鑰,客戶端存公鑰。(服務(wù)器和客戶端關(guān)系可以考慮為 1:N)

客戶端往服務(wù)器傳輸內(nèi)容,更多考慮是隱私性,所以公鑰簽名、私鑰解密。

服務(wù)器往客戶端傳輸內(nèi)容,更多考慮真實(shí)性,所以私鑰簽名,公鑰驗(yàn)簽。

消息的摘要生的算法常用的是MD5或者SHA1,消息內(nèi)容不一樣,生成的摘要信息一定不一樣。

真實(shí)性的考慮一方面是內(nèi)容由私鑰擁有者發(fā)出,另一方面內(nèi)容在傳輸過(guò)程中沒(méi)有改變過(guò),所以簽名的對(duì)象是傳輸信息生成的消息摘要(摘要內(nèi)容短,簽名也會(huì)快些)。

每次加密的長(zhǎng)度需要小于密鑰長(zhǎng)度-特殊位(128位公鑰,最長(zhǎng)可加密128-11=117位明文)。

每次解密的長(zhǎng)度需要小于密鑰的長(zhǎng)度(128位私鑰解密,解密密文長(zhǎng)度需要小于等于128位)。

如果加解密內(nèi)容過(guò)長(zhǎng),就需要分段加密、解密。

PEM格式的密鑰為base64位文本格式。

環(huán)境配置

環(huán)境:MAC

python版本:2.7.15(因?yàn)楣居玫陌姹径际沁@個(gè),建議用python3的)

IED:PyCharm

密鑰:PEM文件

rsa

示例代碼

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

# -*- coding: UTF-8 -*-

# ! /usr/bin/env python

import?base64

import?rsa

from?rsa?import?common

?

?

# 使用 rsa庫(kù)進(jìn)行RSA簽名和加解密

class?RsaUtil(object):

????PUBLIC_KEY_PATH?=?'/Users/anonyper/Desktop/key/company_rsa_public_key.pem'??# 公鑰

????PRIVATE_KEY_PATH?=?'/Users/anonyper/Desktop/key/company_rsa_private_key.pem'??# 私鑰

?

????# 初始化key

????def?__init__(self,

?????????????????company_pub_file=PUBLIC_KEY_PATH,

?????????????????company_pri_file=PRIVATE_KEY_PATH):

?

????????if?company_pub_file:

????????????self.company_public_key?=?rsa.PublicKey.load_pkcs1_openssl_pem(open(company_pub_file).read())

????????if?company_pri_file:

????????????self.company_private_key?=?rsa.PrivateKey.load_pkcs1(open(company_pri_file).read())

?

????def?get_max_length(self, rsa_key, encrypt=True):

????????"""加密內(nèi)容過(guò)長(zhǎng)時(shí) 需要分段加密 換算每一段的長(zhǎng)度.

????????????:param rsa_key: 鑰匙.

????????????:param encrypt: 是否是加密.

????????"""

????????blocksize?=?common.byte_size(rsa_key.n)

????????reserve_size?=?11??# 預(yù)留位為11

????????if?not?encrypt:??# 解密時(shí)不需要考慮預(yù)留位

????????????reserve_size?=?0

????????maxlength?=?blocksize?-?reserve_size

????????return?maxlength

?

????# 加密 支付方公鑰

????def?encrypt_by_public_key(self, message):

????????"""使用公鑰加密.

????????????:param message: 需要加密的內(nèi)容.

????????????加密之后需要對(duì)接過(guò)進(jìn)行base64轉(zhuǎn)碼

????????"""

????????encrypt_result?=?b''

????????max_length?=?self.get_max_length(self.company_public_key)

????????while?message:

????????????input?=?message[:max_length]

????????????message?=?message[max_length:]

????????????out?=?rsa.encrypt(input,?self.company_public_key)

????????????encrypt_result?+=?out

????????encrypt_result?=?base64.b64encode(encrypt_result)

????????return?encrypt_result

?

????def?decrypt_by_private_key(self, message):

????????"""使用私鑰解密.

????????????:param message: 需要加密的內(nèi)容.

????????????解密之后的內(nèi)容直接是字符串,不需要在進(jìn)行轉(zhuǎn)義

????????"""

????????decrypt_result?=?b""

?

????????max_length?=?self.get_max_length(self.company_private_key,?False)

????????decrypt_message?=?base64.b64decode(message)

????????while?decrypt_message:

????????????input?=?decrypt_message[:max_length]

????????????decrypt_message?=?decrypt_message[max_length:]

????????????out?=?rsa.decrypt(input,?self.company_private_key)

????????????decrypt_result?+=?out

????????return?decrypt_result

?

????# 簽名 商戶私鑰 base64轉(zhuǎn)碼

????def?sign_by_private_key(self, data):

????????"""私鑰簽名.

????????????:param data: 需要簽名的內(nèi)容.

????????????使用SHA-1 方法進(jìn)行簽名(也可以使用MD5)

????????????簽名之后,需要轉(zhuǎn)義后輸出

????????"""

????????signature?=?rsa.sign(str(data), priv_key=self.company_private_key,?hash='SHA-1')

????????return?base64.b64encode(signature)

?

????def?verify_by_public_key(self, message, signature):

????????"""公鑰驗(yàn)簽.

????????????:param message: 驗(yàn)簽的內(nèi)容.

????????????:param signature: 對(duì)驗(yàn)簽內(nèi)容簽名的值(簽名之后,會(huì)進(jìn)行b64encode轉(zhuǎn)碼,所以驗(yàn)簽前也需轉(zhuǎn)碼).

????????"""

????????signature?=?base64.b64decode(signature)

????????return?rsa.verify(message, signature,?self.company_public_key)

?

?

message?=?'hell world'

print("明文內(nèi)容:>>> ")

print(message)

rsaUtil?=?RsaUtil()

encrypy_result?=?rsaUtil.encrypt_by_public_key(message)

print("加密結(jié)果:>>> ")

print(encrypy_result)

decrypt_result?=?rsaUtil.decrypt_by_private_key(encrypy_result)

print("解密結(jié)果:>>> ")

print(decrypt_result)

sign?=?rsaUtil.sign_by_private_key(message)

print("簽名結(jié)果:>>> ")

print(sign)

print("驗(yàn)簽結(jié)果:>>> ")

print(rsaUtil.verify_by_public_key(message, sign))

?

#執(zhí)行結(jié)果

明文內(nèi)容:>>>

hell world

加密結(jié)果:>>>

sWx9r30CCLXip0iemCb2r1gsZIedgLp1Vmk9uCDaQttcQNftwQyI98shN2Hpn7snE27ziJnH6qYmaf68TWBerhJVGEzr16wLYInVft0Bj0+kcCmLL7tMJRZWydqHi/YzgIfsFEvqLOUFv6E9bCAXhJkikacBAG4FWTMBrXUQHjE=

解密結(jié)果:>>>

hell world

簽名結(jié)果:>>>

GS3MPpb4zMLIL7mqcxZEevOoH1Fse9fjHefWIUpDaMplhoPUNK85TreYmOwvF8QJNxgLcJoKKfRm51gemsQd1/e1FBPo/4VS3kvneJyLUtQAPdOOl+R4h//0gFec+ELI+KS8A74Dkm2bFKztZ4BxIcWD63pHRiGAnS8+cQeq2QM=

驗(yàn)簽結(jié)果:>>>

True

  

知識(shí)點(diǎn)

  • rsa計(jì)算密鑰長(zhǎng)度的方式是?common.byte_size(rsa_key.n)
  • rsa加密:rsa.encrypt(message, pub_key)
  • rsa解密:rsa.decrypt(crypto, priv_key)
  • rsa簽名:rsa.sign(message, priv_key, hash)
  • rsa驗(yàn)簽:rsa.verify(message, signature, pub_key)
  • rsa默認(rèn)沒(méi)有私鑰加密,公鑰解密的方法(加解密傳入錯(cuò)誤的key會(huì)報(bào)錯(cuò),如果想實(shí)現(xiàn)私鑰加密,公鑰解密可以自行模擬底層代碼實(shí)現(xiàn))
  • 簽名只能用私鑰(用到私鑰的n值,公鑰沒(méi)有n值,n、d、e具體什么意思請(qǐng)百度RSA算法原理)
  • rsa加載公鑰和私鑰的方法不同
  • rsa私鑰簽名時(shí),需要傳入的是不是具體的摘要信息(字符串),而是簽名信息的hash對(duì)象(對(duì)象)
  • 不同版本的rsa驗(yàn)簽成功之后返回結(jié)果不一樣,有的是True,有的是返回生成摘要算法名:如sha1

Crypto

示例代碼

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

# -*- coding: UTF-8 -*-

# ! /usr/bin/env python

import?base64

from?Crypto.Cipher?import?PKCS1_v1_5 as PKCS1_v1_5_cipper

from?Crypto.Signature?import?PKCS1_v1_5

from?Crypto.PublicKey?import?RSA

from?Crypto.Hash?import?SHA

?

import?Crypto

?

?

# 使用 rsa庫(kù)進(jìn)行RSA簽名和加解密

?

?

class?RsaUtil(object):

????PUBLIC_KEY_PATH?=?'/Users/anonyper/Desktop/key/company_rsa_public_key.pem'??# 公鑰

????PRIVATE_KEY_PATH?=?'/Users/anonyper/Desktop/key/company_rsa_private_key.pem'??# 私鑰

?

????# 初始化key

????def?__init__(self,

?????????????????company_pub_file=PUBLIC_KEY_PATH,

?????????????????company_pri_file=PRIVATE_KEY_PATH):

?

????????if?company_pub_file:

????????????self.company_public_key?=?RSA.importKey(open(company_pub_file).read())

????????if?company_pri_file:

????????????self.company_private_key?=?RSA.importKey(open(company_pri_file).read())

?

????def?get_max_length(self, rsa_key, encrypt=True):

????????"""加密內(nèi)容過(guò)長(zhǎng)時(shí) 需要分段加密 換算每一段的長(zhǎng)度.

????????????:param rsa_key: 鑰匙.

????????????:param encrypt: 是否是加密.

????????"""

????????blocksize?=?Crypto.Util.number.size(rsa_key.n)?/?8

????????reserve_size?=?11??# 預(yù)留位為11

????????if?not?encrypt:??# 解密時(shí)不需要考慮預(yù)留位

????????????reserve_size?=?0

????????maxlength?=?blocksize?-?reserve_size

????????return?maxlength

?

????# 加密 支付方公鑰

????def?encrypt_by_public_key(self, encrypt_message):

????????"""使用公鑰加密.

????????????:param encrypt_message: 需要加密的內(nèi)容.

????????????加密之后需要對(duì)接過(guò)進(jìn)行base64轉(zhuǎn)碼

????????"""

????????encrypt_result?=?b''

????????max_length?=?self.get_max_length(self.company_public_key)

????????cipher?=?PKCS1_v1_5_cipper.new(self.company_public_key)

????????while?encrypt_message:

????????????input_data?=?encrypt_message[:max_length]

????????????encrypt_message?=?encrypt_message[max_length:]

????????????out_data?=?cipher.encrypt(input_data)

????????????encrypt_result?+=?out_data

????????encrypt_result?=?base64.b64encode(encrypt_result)

????????return?encrypt_result

?

????# 加密 支付方私鑰

????def?encrypt_by_private_key(self, encrypt_message):

????????"""使用私鑰加密.

????????????:param encrypt_message: 需要加密的內(nèi)容.

????????????加密之后需要對(duì)接過(guò)進(jìn)行base64轉(zhuǎn)碼

????????"""

????????encrypt_result?=?b''

????????max_length?=?self.get_max_length(self.company_private_key)

????????cipher?=?PKCS1_v1_5_cipper.new(self.company_public_key)

????????while?encrypt_message:

????????????input_data?=?encrypt_message[:max_length]

????????????encrypt_message?=?encrypt_message[max_length:]

????????????out_data?=?cipher.encrypt(input_data)

????????????encrypt_result?+=?out_data

????????encrypt_result?=?base64.b64encode(encrypt_result)

????????return?encrypt_result

?

????def?decrypt_by_public_key(self, decrypt_message):

????????"""使用公鑰解密.

????????????:param decrypt_message: 需要解密的內(nèi)容.

????????????解密之后的內(nèi)容直接是字符串,不需要在進(jìn)行轉(zhuǎn)義

????????"""

????????decrypt_result?=?b""

????????max_length?=?self.get_max_length(self.company_public_key,?False)

????????decrypt_message?=?base64.b64decode(decrypt_message)

????????cipher?=?PKCS1_v1_5_cipper.new(self.company_public_key)

????????while?decrypt_message:

????????????input_data?=?decrypt_message[:max_length]

????????????decrypt_message?=?decrypt_message[max_length:]

????????????out_data?=?cipher.decrypt(input_data, '')

????????????decrypt_result?+=?out_data

????????return?decrypt_result

?

????def?decrypt_by_private_key(self, decrypt_message):

????????"""使用私鑰解密.

????????????:param decrypt_message: 需要解密的內(nèi)容.

????????????解密之后的內(nèi)容直接是字符串,不需要在進(jìn)行轉(zhuǎn)義

????????"""

????????decrypt_result?=?b""

????????max_length?=?self.get_max_length(self.company_private_key,?False)

????????decrypt_message?=?base64.b64decode(decrypt_message)

????????cipher?=?PKCS1_v1_5_cipper.new(self.company_private_key)

????????while?decrypt_message:

????????????input_data?=?decrypt_message[:max_length]

????????????decrypt_message?=?decrypt_message[max_length:]

????????????out_data?=?cipher.decrypt(input_data, '')

????????????decrypt_result?+=?out_data

????????return?decrypt_result

?

????# 簽名 商戶私鑰 base64轉(zhuǎn)碼

????def?sign_by_private_key(self, message):

????????"""私鑰簽名.

????????????:param message: 需要簽名的內(nèi)容.

????????????簽名之后,需要轉(zhuǎn)義后輸出

????????"""

????????cipher?=?PKCS1_v1_5.new(self.company_private_key)??# 用公鑰簽名,會(huì)報(bào)錯(cuò) raise TypeError("No private key") 如下

????????# if not self.has_private():

????????#?? raise TypeError("No private key")

????????hs?=?SHA.new(message)

????????signature?=?cipher.sign(hs)

????????return?base64.b64encode(signature)

?

????def?verify_by_public_key(self, message, signature):

????????"""公鑰驗(yàn)簽.

????????????:param message: 驗(yàn)簽的內(nèi)容.

????????????:param signature: 對(duì)驗(yàn)簽內(nèi)容簽名的值(簽名之后,會(huì)進(jìn)行b64encode轉(zhuǎn)碼,所以驗(yàn)簽前也需轉(zhuǎn)碼).

????????"""

????????signature?=?base64.b64decode(signature)

????????cipher?=?PKCS1_v1_5.new(self.company_public_key)

????????hs?=?SHA.new(message)

?

????????# digest = hashlib.sha1(message).digest()? # 內(nèi)容摘要的生成方法有很多種,只要簽名和解簽用的是一樣的就可以

?

????????return?cipher.verify(hs, signature)

?

?

?

message?=?'hell worldhell worldhell worldhell worldhell worldhell worldhell worldhell worldhell worldhell worldhell worldhell worldhell worldhell worldhell worldhell worldhell worldhell worldhell world'

print("明文內(nèi)容:>>> ")

print(message)

rsaUtil?=?RsaUtil()

encrypy_result?=?rsaUtil.encrypt_by_public_key(message)

print("加密結(jié)果:>>> ")

print(encrypy_result)

decrypt_result?=?rsaUtil.decrypt_by_private_key(encrypy_result)

print("解密結(jié)果:>>> ")

print(decrypt_result)

sign?=?rsaUtil.sign_by_private_key(message)

print("簽名結(jié)果:>>> ")

print(sign)

print("驗(yàn)簽結(jié)果:>>> ")

print(rsaUtil.verify_by_public_key(message, sign))

?

#執(zhí)行結(jié)果:

明文內(nèi)容:>>>

hell worldhell worldhell worldhell worldhell worldhell worldhell worldhell worldhell worldhell worldhell worldhell worldhell worldhell worldhell worldhell worldhell worldhell worldhell world

加密結(jié)果:>>>

PC8/knkmszKby2pHtlKJa/Uv7EADImNhrFwZQK3YHpwPwDpt5A4bFTxsDu2o8U0yc+X50+M3Bi53C0sOHjiOCStG/Bp1nfowHQBgUFCETp4G3fpLAl7eWynqqu6gInjHQeNMbBz1wvRhSiXoMB2lJm8b9fLuzDuQQRFZPqD356kgTKnBM+lju4HE4zMjAT8jMam5Z4EnmaRfX7kYDGzga+PgbkkGon354i3CRhuRWtpvQeXnmjZq8MpfDC6//L7I/vvw4/LMJhiQJkXUbGEgSok8yg6jZzGx+bllc+qn7DH5nkNZKkOnqaeJHbEktgdhua/QXJcRR/5Lm0Y8ovs54A==

解密結(jié)果:>>>

hell worldhell worldhell worldhell worldhell worldhell worldhell worldhell worldhell worldhell worldhell worldhell worldhell worldhell worldhell worldhell worldhell worldhell worldhell world

簽名結(jié)果:>>>

VinHhT+iJfDvIgseJ0ZsmJcLk+yDdx0323B6vMKMUHDlUF2HDWqQhEEoqmSstjsSfR/T+4829t5DhtaJ5w1O7K7ZyP/+yu/lupc8apmfYSIziozi3vPy20p/CYNaXAy0LLGOwrtVNn3jTaq7Gb0yI4/Zhin2jNmTk09g8Qx9rGI=

驗(yàn)簽結(jié)果:>>>

True

  

知識(shí)點(diǎn)

  • Crypto計(jì)算密鑰長(zhǎng)度的方法是 Crypto.Util.number.size(rsa_key.n) / 8(一個(gè)字節(jié)8位)
  • Crypto導(dǎo)入密鑰的方法是同一個(gè) RSA.importKey(self, externKey, passphrase=None),externKey為密鑰內(nèi)容
  • Crypto加密方法:Crypto.Cipher.PKCS1_v1_5.new(key).encrypt(self, message)
  • Crypto解密方法:Crypto.Cipher.PKCS1_v1_5.new(key).decrypt(self, message)
  • Crypto簽名方法:Crypto.Signature.PKCS1_v1_5.new(key).sign(self, mhash)
  • Crypto驗(yàn)簽方法:Crypto.Signature.PKCS1_v1_5_cipper.new(key).verifyverify(self, mhash, S)
  • Crypto公鑰、私鑰都可以互相加解密
  • Crypto只能私鑰簽名,公鑰驗(yàn)簽,簽名傳入公鑰會(huì)報(bào)錯(cuò)(底層有key.has_private()判斷)
  • Crypto私鑰簽名時(shí),需要傳入的是消息的摘要內(nèi)容,所以摘要可以由不同的實(shí)現(xiàn)方式只要驗(yàn)簽時(shí)摘要算法一致即可。
  • Crypto驗(yàn)簽之后成功返回結(jié)果True(不知道會(huì)不會(huì)與其他的)

M2Crypto

示例代碼

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

# -*- coding: UTF-8 -*-

# ! /usr/bin/env python

import?base64

import?M2Crypto

from?M2Crypto?import?EVP

?

?

# 使用 M2Crypto庫(kù)進(jìn)行RSA簽名和加解密

class?RsaUtil(object):

????PUBLIC_KEY_PATH?=?'/Users/anonyper/Desktop/key/company_rsa_public_key.pem'??# 公鑰

????PRIVATE_KEY_PATH?=?'/Users/anonyper/Desktop/key/company_rsa_private_key.pem'??# 私鑰

?

????# 初始化key

????def?__init__(self,

?????????????????company_pub_file=PUBLIC_KEY_PATH,

?????????????????company_pri_file=PRIVATE_KEY_PATH):

?

????????if?company_pub_file:

????????????self.company_public_key?=?M2Crypto.RSA.load_pub_key(company_pub_file)

????????if?company_pri_file:

????????????self.company_private_key?=?M2Crypto.RSA.load_key(company_pri_file)

?

????def?get_max_length(self, rsa_key, encrypt=True):

????????"""加密內(nèi)容過(guò)長(zhǎng)時(shí) 需要分段加密 換算每一段的長(zhǎng)度.

????????????:param rsa_key: 鑰匙.

????????????:param encrypt: 是否是加密.

????????"""

????????blocksize?=?rsa_key.__len__()?/?8

????????reserve_size?=?11??#

????????if?not?encrypt:

????????????reserve_size?=?0

????????maxlength?=?blocksize?-?reserve_size

????????return?maxlength

?

????# 加密 支付方公鑰

????def?encrypt_by_public_key(self, encrypt_message):

????????"""使用公鑰加密.

????????????:param encrypt_message: 需要加密的內(nèi)容.

????????????加密之后需要對(duì)接過(guò)進(jìn)行base64轉(zhuǎn)碼

????????"""

????????encrypt_result?=?b''

????????max_length?=?self.get_max_length(self.company_public_key)

????????print(max_length)

????????while?encrypt_message:

????????????input_data?=?encrypt_message[:max_length]

????????????encrypt_message?=?encrypt_message[max_length:]

????????????out_data?=?self.company_public_key.public_encrypt(input_data, M2Crypto.RSA.pkcs1_padding)

????????????encrypt_result?+=?out_data

????????encrypt_result?=?base64.b64encode(encrypt_result)

????????return?encrypt_result

?

????# 加密 支付方私鑰

????def?encrypt_by_private_key(self, encrypt_message):

????????"""使用私鑰加密.

????????????:param encrypt_message: 需要加密的內(nèi)容.

????????????加密之后需要對(duì)接過(guò)進(jìn)行base64轉(zhuǎn)碼

????????"""

????????encrypt_result?=?b''

????????max_length?=?self.get_max_length(self.company_private_key)

????????while?encrypt_message:

????????????input_data?=?encrypt_message[:max_length]

????????????encrypt_message?=?encrypt_message[max_length:]

????????????out_data?=?self.company_private_key.private_encrypt(input_data, M2Crypto.RSA.pkcs1_padding)

????????????encrypt_result?+=?out_data

????????encrypt_result?=?base64.b64encode(encrypt_result)

????????return?encrypt_result

?

????def?decrypt_by_public_key(self, decrypt_message):

????????"""使用公鑰解密.

????????????:param decrypt_message: 需要解密的內(nèi)容.

????????????解密之后的內(nèi)容直接是字符串,不需要在進(jìn)行轉(zhuǎn)義

????????"""

????????decrypt_result?=?b""

????????max_length?=?self.get_max_length(self.company_private_key,?False)

????????decrypt_message?=?base64.b64decode(decrypt_message)

????????while?decrypt_message:

????????????input_data?=?decrypt_message[:max_length]

????????????decrypt_message?=?decrypt_message[max_length:]

????????????out_data?=?self.company_public_key.public_encrypt(input_data, M2Crypto.RSA.pkcs1_padding)

????????????decrypt_result?+=?out_data

????????return?decrypt_result

?

????def?decrypt_by_private_key(self, decrypt_message):

????????"""使用私鑰解密.

????????????:param decrypt_message: 需要解密的內(nèi)容.

????????????解密之后的內(nèi)容直接是字符串,不需要在進(jìn)行轉(zhuǎn)義

????????"""

????????decrypt_result?=?b""

????????max_length?=?self.get_max_length(self.company_private_key,?False)

????????decrypt_message?=?base64.b64decode(decrypt_message)

????????while?decrypt_message:

????????????input_data?=?decrypt_message[:max_length]

????????????decrypt_message?=?decrypt_message[max_length:]

????????????out_data?=?self.company_private_key.private_decrypt(input_data, M2Crypto.RSA.pkcs1_padding)

????????????decrypt_result?+=?out_data

????????return?decrypt_result

?

????# 簽名 商戶私鑰 base64轉(zhuǎn)碼

????def?sign_by_private_key(self, message):

????????"""私鑰簽名.

????????????:param message: 需要簽名的內(nèi)容.

????????????簽名之后,需要轉(zhuǎn)義后輸出

????????"""

????????hs?=?EVP.MessageDigest('sha1')

????????hs.update(message)

????????digest?=?hs.final()

????????# digest = hashlib.sha1(message).digest() # 內(nèi)容摘要的生成方法有很多種,只要簽名和解簽用的是一樣的就可以

????????signature?=?self.company_private_key.sign(digest)

????????# self.company_public_key.sign(digest)? # 用公鑰簽名IDE會(huì)崩

????????return?base64.b64encode(signature)

?

????def?verify_by_public_key(self, message, signature):

????????"""公鑰驗(yàn)簽.

????????????:param message: 驗(yàn)簽的內(nèi)容.

????????????:param signature: 對(duì)驗(yàn)簽內(nèi)容簽名的值(簽名之后,會(huì)進(jìn)行b64encode轉(zhuǎn)碼,所以驗(yàn)簽前也需轉(zhuǎn)碼).

????????"""

????????hs?=?EVP.MessageDigest('sha1')

????????hs.update(message)

????????digest?=?hs.final()

????????# digest = hashlib.sha1(message).digest()? # 內(nèi)容摘要的生成方法有很多種,只要簽名和解簽用的是一樣的就可以

????????signature?=?base64.b64decode(signature)

????????return?self.company_public_key.verify(digest, signature)

?

?

message?=?'hell worldhell worldhell worldhell worldhell worldhell worldhell worldhell worldhell worldhell worldhell worldhell worldhell worldhell worldhell worldhell worldhell worldhell worldhell world'

print("明文內(nèi)容:>>> ")

print(message)

rsaUtil?=?RsaUtil()

encrypy_result?=?rsaUtil.encrypt_by_public_key(message)

print("加密結(jié)果:>>> ")

print(encrypy_result)

decrypt_result?=?rsaUtil.decrypt_by_private_key(encrypy_result)

print("解密結(jié)果:>>> ")

print(decrypt_result)

sign?=?rsaUtil.sign_by_private_key(message)

print("簽名結(jié)果:>>> ")

print(sign)

print("驗(yàn)簽結(jié)果:>>> ")

print(rsaUtil.verify_by_public_key(message, sign))

?

?

#執(zhí)行結(jié)果

明文內(nèi)容:>>>

hell worldhell worldhell worldhell worldhell worldhell worldhell worldhell worldhell worldhell worldhell worldhell worldhell worldhell worldhell worldhell worldhell worldhell worldhell world

加密結(jié)果:>>>

fu4RgyOaokEcLmA5k0otMirZoiFBDBkEgycgehEajtPU+xP7Wf5rN05kwbsDNI7/kUR5wOvS0XE8jD1nYmKv4uBWfR5Z28BHdK20uue/8zTnPgdsAmRdzA6Lb2EIk/g38o2EtRZ4jILNOdikpW0kYpYRdaJgoHTWTOlE/RL9zcVKzYELFPpWui2jZ8EVMe+6ZiPkRKCKL571f/OTb1qOdg4GTiowZCNMIknTxXawvZl9Funz7TNz0WsNDejL+r3tM8erwhE0ygIMtemOiVy8yBVsHpHPzfdlNRoXXgtgupFEgVgEOODUp9y4LzX6UDf0+i8uI7/SpyQoa9jSpcsIjA==

解密結(jié)果:>>>

hell worldhell worldhell worldhell worldhell worldhell worldhell worldhell worldhell worldhell worldhell worldhell worldhell worldhell worldhell worldhell worldhell worldhell worldhell world

簽名結(jié)果:>>>

VinHhT+iJfDvIgseJ0ZsmJcLk+yDdx0323B6vMKMUHDlUF2HDWqQhEEoqmSstjsSfR/T+4829t5DhtaJ5w1O7K7ZyP/+yu/lupc8apmfYSIziozi3vPy20p/CYNaXAy0LLGOwrtVNn3jTaq7Gb0yI4/Zhin2jNmTk09g8Qx9rGI=

驗(yàn)簽結(jié)果:>>>

1

  

知識(shí)點(diǎn)

  • M2Crypto計(jì)算密鑰長(zhǎng)度的方法是 rsa_key.len() / 8(一個(gè)字節(jié)8位)
  • M2Crypto導(dǎo)入密鑰的方法是不同 M2Crypto.RSA.load_pub_key(file),M2Crypto.RSA.load_key(file)//還有其他的,不列舉了,使用load_key(file)傳入公鑰地址會(huì)報(bào)錯(cuò)。
  • M2Crypto加密解密代碼:(RSA class下)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

def?public_encrypt(self, data, padding):

????# type: (bytes, int) -> bytes

????assert?self.check_key(),?'key is not initialised'

????return?m2.rsa_public_encrypt(self.rsa, data, padding)

?

def?public_decrypt(self, data, padding):

????# type: (bytes, int) -> bytes

????assert?self.check_key(),?'key is not initialised'

????return?m2.rsa_public_decrypt(self.rsa, data, padding)

?

def?private_encrypt(self, data, padding):

????# type: (bytes, int) -> bytes

????assert?self.check_key(),?'key is not initialised'

????return?m2.rsa_private_encrypt(self.rsa, data, padding)

?

def?private_decrypt(self, data, padding):

????# type: (bytes, int) -> bytes

????assert?self.check_key(),?'key is not initialised'

????return?m2.rsa_private_decrypt(self.rsa, data, padding)

  

  • 公鑰和私鑰具體實(shí)現(xiàn)RSA的代碼:

1

2

3

4

5

6

7

8

9

10

11

12

13

class?RSA_pub(RSA):

?

????"""

????Object interface to an RSA public key.

????"""

????#公鑰調(diào)用下面方法直接報(bào)錯(cuò)

????def?private_encrypt(self,?*argv):

????????# type: (*Any) -> None

????????raise?RSAError('RSA_pub object has no private key')

????#公鑰調(diào)用下面方法直接報(bào)錯(cuò)

????def?private_decrypt(self,?*argv):

????????# type: (*Any) -> None

????????raise?RSAError('RSA_pub object has no private key')

  

  • M2Crypto簽名和驗(yàn)簽 sign(self, digest, algo='sha1'):/verify(self, data, signature, algo='sha1'):
  • M2Crypto公鑰、私鑰都可以互相加解密
  • M2Crypto只能私鑰簽名,公鑰驗(yàn)簽,簽名傳入公鑰會(huì)報(bào)錯(cuò)(公鑰可以調(diào)用簽名方法,但是IDE崩潰了)
  • M2Crypto私鑰簽名時(shí),需要傳入的是消息的摘要內(nèi)容,所以摘要可以由不同的實(shí)現(xiàn)方式只要驗(yàn)簽時(shí)摘要算法一致即可。
  • M2Crypto驗(yàn)簽之后成功返回結(jié)果1(不知道會(huì)不會(huì)與其他的)

其他注意事項(xiàng)

  • base64位encode和decode時(shí),可以傳入編碼集,UTF-8會(huì)將+轉(zhuǎn)化為u,將/轉(zhuǎn)化為t
  • 在和服務(wù)器交互時(shí),‘+’、‘=’、‘/’ 等特殊字符可能會(huì)被轉(zhuǎn)義,造成客戶端和服務(wù)器內(nèi)容細(xì)微的不一致而導(dǎo)致驗(yàn)簽失敗,尤其是兩邊使用的語(yǔ)言不通,所以要協(xié)商好轉(zhuǎn)義方案。
  • 更多資訊或疑問(wèn)內(nèi)容添加小編微信,?回復(fù) “Python” ,領(lǐng)取更多資料哦

    ? ?? ?

總結(jié)

以上是生活随笔為你收集整理的python RSA加密、解密、签名的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。