python3 rsa非对称加密与签名校验

背景

加密分为对称加密和非对称加密,非对称加密拥有更高的安全性。另外最近在使用百度统计api时碰到了使用python非对称加密的问题。

一个密钥对包含公钥和私钥,公钥是公开的,私钥由个人保存。公钥和私钥由n,e,d三个数字组成,公钥为(e,n),私钥为(d,n).

RSA的实际用途有两个:

  1. 加密,是希望密文只有接收方可以解密,也就只能由接收方用自己的私钥解密,所以发送方用接收方的公钥加密信息后发送给接收方。
  2. 签名,是希望接收方可以肯定信息是由发送方发来的,那么信息就必须用只有发送方知道的密钥加密也就是用发送方的私钥加密,然后接收方用发送方的公钥解密,以判断信息是不是由发送方发来。

明文长度与密文长度

密文长度肯定都是n的倍数。如果原始明文长度不够,会有字节填充。若原始明文长度过长,那么进行分块加密

如果要分块加密,明文使用PKCS1PADDING填充,这会默认占用11个字节的明文空间,若n为1024位即128字节,则只有117字节明文可以加密。

代码

以下代码适配python3

不分块加密

1
2
3
4
5
6
7
8
9
10
11
12
import rsa
key = rsa.newkeys(1024)#生成随机秘钥
privateKey = key[1]#私钥
publicKey = key[0]#公钥
message ='sanxi Now is better than never.'
print('Before encrypted:',message)
message = message.encode()
cryptedMessage = rsa.encrypt(message, publicKey)
print('After encrypted:\n',cryptedMessage)
message = rsa.decrypt(cryptedMessage, privateKey)
message = message.decode()
print('After decrypted:',message)

大数据分块加密 & 从文件load公钥

注意:需要在本地有一个公钥文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import rsa
import math
def encrypt(data):
# load公钥和密钥
with open('api_pub.key') as publickfile:
p = publickfile.read()
pubkey = rsa.PublicKey.load_pkcs1_openssl_pem(p)
# 用公钥加密
n = int(math.ceil(len(data) * 1.0 / 117))
ret = b''
for i in range(n):
gzdata = data[i * 117:(i + 1) * 117]
ret += rsa.encrypt(gzdata, pubkey)
return ret

签名

1
2
3
4
5
6
7
8
9
10
11
12
import rsa
key = rsa.newkeys(1024)#生成随机秘钥
privateKey = key[1]#私钥
publicKey = key[0]#公钥
message = 'coding now!'.encode('utf8')
# 签名,参数为明文、发送方私钥、hash算法
# 可选的哈希函数有 MD5 SHA-1 SHA-256 SHA-384 SHA-512
# 在rsa.verify()中可以自动识别出hash值采用的算法,因为每种hash算法得到的hash值位数是不同的。
signature = rsa.sign(message, privateKey ,'SHA-1')
#验证,参数为明文、签名信息、发送方公钥
verification = rsa.verify(message,signature, publicKey)
print(verification)
0%