python RSA生成公钥和私钥

3,309 阅读3分钟

一、什么是公钥和私匙

公钥(Public Key)与私匙(Private Key)是通过一种算法得到的一个密匙对(即一个公钥和一个私钥),是非对称加密。

公钥和私钥是成对的,它们互相解密。
公钥加密,私钥解密。
私钥数字签名,公钥验证。

二、RSA验签过程

私钥产生签名,公钥验证签名

  1. 服务端产生公钥和私钥
# -*- coding:utf-8 -*-
import rsa
import base64


# 生成RSA公钥和私钥
(pubkey, privkey) = rsa.newkeys(2048)

# 经过base64编码
# pubkey = base64.encodebytes(pubkey.save_pkcs1())
# privkey = base64.encodebytes(privkey.save_pkcs1())


# 生成公钥
pub_key = pubkey.save_pkcs1()
pub_file = open('api_public_key.key', 'wb')
pub_file.write(pub_key)
pub_file.close()
print(pub_key)

# 生成私钥
private_key = privkey.save_pkcs1()
pri_file = open('api_private_key.key', 'wb')
pri_file.write(private_key)
pri_file.close()

print(private_key)

2 签名步骤:

客户端
a. 将所有请求的参数收集准备
b. 新增一个当前时间time=16060000000001900毫秒数)当作一个参数值
c. 将所有参数用KEY排序,生成字符串。如: a=100&b=200&time=1600000
d. 拼接url+参数完整路径
e. 用SHA256算法,使用私钥签名。签名结果编码成base64

Server端验证签名
r = rsa.verify(sign_str, base64.b64decode(sign), public_key)
print(r)
print(type(r))
# -*- coding: utf-8 -*-

import base64
import urllib
import rsa
import time


private_key_str = '''-----BEGIN RSA PRIVATE KEY-----
MIIEqAIBAAKCAQEAzRcbxrlrBu1I1yB4ORX3i1Kx9FhLVD9ax/zxd42wq3W4J3Oz
oqZf4QJzR3iV/3xGezj+xyWxL9jXIlIJe9+Ii6STSevOeiZp8aeuPybqL2ExIGir
EV3/HVt8WoHC5IrqOWwHN52LScVQSjsIUU3tWFmndFBqoB5U4j0ot1PXN/k0ROGP
VNx27D5tw2VIQR9Y8pJDCDtdw6XItAqh/hBf8bD3Cpr8dK+KdySPsZhqYbI6X39K
Ekp0oD7qW7eeGcnzo0oww9ousIMAEOMw3A4r1jMmaG/kDm3ujmv/PJ5eteV6iSJa
x/JzGjKG0lwJNepKUObIJXI+/uRkmANSw+vBWQIDAQABAoIBAAWVM3RdZ8RwgSMa
ByvGpU5tmdqE7MgGUXpQMGKIwN5p/fFU/PbYgJOndWvkpHCn+WMxUf4p0ID07iZJ
BWkR1K24dSn1+VDp6shhQCUH8igIBUZUkxON83vhGal9DskZ3vZhMnEZIMmJTX43
zSopbOSSzDQmXECvkqoBPHhHT3L7vMmgQRdgxLNPdZ2bQX2airUDL9hK06ZZ2T0V
JlmMprHl+tOP7BASpMpFU+LfHp+WnqKtCK0fVFX0Dnkb27zT5nYmMDioo1Gp5fBn
QNzObm3u/dy9oCZI6DNp/7/Qj6JkqQh9/6wwQ4EHaE5wvxu2kzfgilhmPN1mjA+G
hEZ5AAECgYkA2sqUaLjm9hTJ4pRBUkxhq5IO1YPODLOytvrg4j3j4pDjGDiDJi1K
hyG7DrxJOmokD7up/moy2McOsOcYALwN5r16g526hO2VG8FQ8GSfahCp1mYcYYNF
wSSA6Sk1WPrvGqMAxKmRKI7kw/r2xP9R0JOJKew8U4ngMk13Kk+HE92TPY/xxU25
WQJ5AO/4CCjIJOsH4A4Tlhvn6p/clAQjnzSOKZoJQFq8aYYjHaKPkpsPinZU0s2r
cfxl93C63qeLFqJ/ht4PDwfuOjfYxKY5x48Gv1Qg8ZLlQDQTfvMD8r7tRYwMa8AM
c3YLSlnrmVyi6r6zz/8q9nXEBhauCt6+acVIAQKBiGGlYeDvDN0s4AFIi3KwdjK9
Z/Nw9MgEdzFk/HLcjlUytre7mQSz1/xBWJu1+rSgZGHFLpRGT1UiWfMn4DWLuGSP
khsljPYAlrihaX8wWVlcAICYZ/g5Pyt5IDNvWcjRjV8E+rXKu+cvBvhUjEfVb204
O1JDhZT/BtlMa2+tuKpsDGfAU3XsP1kCeGCMarv9ytzFTmBbgQm5Ra0MEoGX03ZR
vGs9Tac0J0DQ4BuHqHS6y/rQJgCZ+kKSw/uXM/409+ZpaNnvNRz7vHC7xmMa3C+v
h0tR9eAkXLCXJ3yfGgu3a0Ptu2yJlerooAGNySZ8ZfZUYltH7eFz/P8jBzyXX/cA
AQKBiGfhRN6aMpWQyB30C3ZsU4Dm/b06yVcRRihlSoZROdfrB57AIKESEnOtUD4V
Fs7r0xoUvOyGCb3kEm+lSXcRJTQYGspvqhMPjEFmQSGncEuR788MidDAZWwHoL4J
ON/x1xAWffRbRxmA8XQYTQQD/XppMIZYphwzzXJQzGlcchvEx+fxnzXAsB0=
-----END RSA PRIVATE KEY-----
'''


public_key_str = """-----BEGIN RSA PUBLIC KEY-----
MIIBCgKCAQEAzRcbxrlrBu1I1yB4ORX3i1Kx9FhLVD9ax/zxd42wq3W4J3OzoqZf
4QJzR3iV/3xGezj+xyWxL9jXIlIJe9+Ii6STSevOeiZp8aeuPybqL2ExIGirEV3/
HVt8WoHC5IrqOWwHN52LScVQSjsIUU3tWFmndFBqoB5U4j0ot1PXN/k0ROGPVNx2
7D5tw2VIQR9Y8pJDCDtdw6XItAqh/hBf8bD3Cpr8dK+KdySPsZhqYbI6X39KEkp0
oD7qW7eeGcnzo0oww9ousIMAEOMw3A4r1jMmaG/kDm3ujmv/PJ5eteV6iSJax/Jz
GjKG0lwJNepKUObIJXI+/uRkmANSw+vBWQIDAQAB
-----END RSA PUBLIC KEY-----
"""

private_key = rsa.PrivateKey.load_pkcs1(private_key_str)
public_key = rsa.PublicKey.load_pkcs1(public_key_str)

# 1.将所有请求的参数收集准备
params = {

}
# 2.新增一个当前时间time=1606000000000(1900毫秒数)当作一个参数值
print(time.time())
now = int(round(time.time() * 1000))
params.update({'time': now})

# 3.将所有参数用KEY排序,生成字符串。如: a=100&b=200&time=1600000
p_list = []
keys = params.keys()
print(keys)
sorted(keys)
for key in keys:
    p_list.append("{0}={1}".format(key, params[key]))

# 4.拼接url+参数完整路径
api_url = '/api/v1/node/XXJHt1Sfk5EeFSclO6luY0DmsVJHlZ1LXzD8SDozimry8xndSTqbAseQ@BEaaZ5W/?'
sign_str = '&'.join(p_list)
print(api_url+sign_str)
sign_str = bytes(api_url+sign_str, "utf-8")

print(type(sign_str))

# 5.用SHA256算法,使用私钥签名。签名结果编码成base64
sign = rsa.sign(sign_str, private_key, "SHA-256")
sign = base64.b64encode(sign)
print(sign)


# 6.Server端验证签名
r = rsa.verify(sign_str, base64.b64decode(sign), public_key)
print(r)
print(type(r))