栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

python实现java中的md5withRSA算法

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

python实现java中的md5withRSA算法

python实现java中的md5withRSA算法
    • 背景
    • md5withRSA加签和验签名原理简单介绍
    • 总结

背景

我需要测试open API提供给第三方的查询接口,本身接口没有什么难度,由于安全规范,需要验证数字签名,该接口要求每次请求传入10位之内的随机数,当前的时间戳,以及用户的邮箱,拼接而成的字符串用于生成数字签名,比如:nonce=99999923×tamp=1632747148774&userName=qyzhg113@core.qyzhg.com,通过md5withRSA算法加密生成的字符串,放在query请求参数中,服务器那边做验证签名,因为每次都有时间戳,和随机数的校验,所以用postman不好测试(postman应该可以用js写,奈何本人不会js),所以用python 来实现,本身也是做一个记录。

md5withRSA加签和验签名原理简单介绍

此处不讨论加密算法的原理,本人数学不咋样,就不献丑了,来说一说,通常加签和验签的流程。
1.约定公钥和私钥,RSA算法会生成一对公钥和私钥,暴露接口一方会提供私钥给使用接口的一方,公钥和私钥不清楚的可以自行百度,这里不做过多说明
例子:

test_private_key = '''
MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAL0CpOl9vtJqj9t8osGZagTPi5lm5IUal8yyZbK27J2iwqhocfCTxPns3VfGgqnJerrUQAKBYk1oQ61aA7aJ0flxEtG2IcH2lF3WmqvDLP9BHJQtXRs/oQdEniz9Im3SYNU5rR0c5owJk1P0HC8Sume1UlbFPJOiPl9PUZk01DBnAgMBAAECgYBAg0OIkqvsJAUgFGV1EQkXxUNPw8fiCpaffpCptDgFAgXQ931UcQt9hrRx/kag7y0d0c5bTJAh/aGD7MJxro7lLqbsSs5GAW6h4E6a7bJKWq3z61figwO/7SY2Ym9/NzaWCUo+CZosdDDwv3yTkqZ5ZeZZ409CG+5YEgpODAvjWQJBAPoGvf8F706hmSzYX/PHRVju1FAcgwxhrM7kUyuUNSCeqBfGO6KaFo7PiRm2+xtrvlLZt1s2l5sLYiF+WrHhx20CQQDBhrRaI6crsGYHrX+64AJWxiLpiM93ZVxlJyOMKHNIGDN5W1u0r4VlASWFs/Z2EKTTU874NQE4wn2L6rRIK06jAkA2dqmEmAJdGo6HWkrsi4frq3rMSKmzVMOT/eCwKYS5KlZrd18eOHqZeVPgKh/hBUNcQNjUIbw8peomaaPQA+KxAkEAivxOLGpsldDjBeKR2EknBODZk/UAYtQ17iOUwQUP/hf7Z8235+UinS6cnxBnEdXUOj13aATRMs1jUwgln6sSlwJBAOQeTxCeKx/Dj9660/nZgek8ez3kcshK+mlz04kIQzG+XSzE3G9joYMYoLz/CIc+xyYXCqqasL/h2hOpB/kj0kI=
'''

test_public_key = '''
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC9AqTpfb7Sao/bfKLBmWoEz4uZZuSFGpfMsmWytuydosKoaHHwk8T57N1XxoKpyXq61EACgWJNaEOtWgO2idH5cRLRtiHB9pRd1pqrwyz/QRyULV0bP6EHRJ4s/SJt0mDVOa0dHOaMCZNT9BwvErpntVJWxTyToj5fT1GZNNQwZwIDAQAB
'''

2.使用私钥生成签名,这里用到Cypto库,具体代码实现如下

from string import Template
import time
from faker import Faker
from Crypto.PublicKey import RSA
from Crypto.Signature import PKCS1_v1_5
from Crypto.Hash import MD5
import base64
import urllib.parse
import requests

test_private_key = '''
MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAL0CpOl9vtJqj9t8osGZagTPi5lm5IUal8yyZbK27J2iwqhocfCTxPns3VfGgqnJerrUQAKBYk1oQ61aA7aJ0flxEtG2IcH2lF3WmqvDLP9BHJQtXRs/oQdEniz9Im3SYNU5rR0c5owJk1P0HC8Sume1UlbFPJOiPl9PUZk01DBnAgMBAAECgYBAg0OIkqvsJAUgFGV1EQkXxUNPw8fiCpaffpCptDgFAgXQ931UcQt9hrRx/kag7y0d0c5bTJAh/aGD7MJxro7lLqbsSs5GAW6h4E6a7bJKWq3z61figwO/7SY2Ym9/NzaWCUo+CZosdDDwv3yTkqZ5ZeZZ409CG+5YEgpODAvjWQJBAPoGvf8F706hmSzYX/PHRVju1FAcgwxhrM7kUyuUNSCeqBfGO6KaFo7PiRm2+xtrvlLZt1s2l5sLYiF+WrHhx20CQQDBhrRaI6crsGYHrX+64AJWxiLpiM93ZVxlJyOMKHNIGDN5W1u0r4VlASWFs/Z2EKTTU874NQE4wn2L6rRIK06jAkA2dqmEmAJdGo6HWkrsi4frq3rMSKmzVMOT/eCwKYS5KlZrd18eOHqZeVPgKh/hBUNcQNjUIbw8peomaaPQA+KxAkEAivxOLGpsldDjBeKR2EknBODZk/UAYtQ17iOUwQUP/hf7Z8235+UinS6cnxBnEdXUOj13aATRMs1jUwgln6sSlwJBAOQeTxCeKx/Dj9660/nZgek8ez3kcshK+mlz04kIQzG+XSzE3G9joYMYoLz/CIc+xyYXCqqasL/h2hOpB/kj0kI=
'''

test_public_key = '''
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC9AqTpfb7Sao/bfKLBmWoEz4uZZuSFGpfMsmWytuydosKoaHHwk8T57N1XxoKpyXq61EACgWJNaEOtWgO2idH5cRLRtiHB9pRd1pqrwyz/QRyULV0bP6EHRJ4s/SJt0mDVOa0dHOaMCZNT9BwvErpntVJWxTyToj5fT1GZNNQwZwIDAQAB
'''


# 获取时间戳
def get_timestamp():
    return int(time.time() * 1000)


# 获取6位随机数
def get_nonce():
    fake = Faker()
    return fake.random_int(min=100000, max=999999)


# 将字符串使用MD5进行加密
def my_hash(data):
    return MD5.new(data.encode('utf-8'))


# 使用约定的私钥生成签名
def rsa_sign(data):
    private_key_bytes = base64.b64decode(test_private_key)
    pri_key = RSA.importKey(private_key_bytes)
    signer = PKCS1_v1_5.new(pri_key)
    hash_obj = my_hash(data)
    signature = base64.b64encode(signer.sign(hash_obj))
    return signature


# 使用约定的公钥验证签名
def rsa_verify(signature, data):
    public_key_bytes = base64.b64decode(test_public_key)
    pub_key = RSA.importKey(public_key_bytes)
    hash_obj = my_hash(data)
    verifier = PKCS1_v1_5.new(pub_key)
    return verifier.verify(hash_obj, base64.b64decode(signature))

例子:
待加密的字符串:

test_data = "apiCode=fa4e05682c474619d29cbf3df4a9f69a&entCode=0fe827b0ce0c2f1249642119bc3efcdb&nonce=99999923×tamp=1632747148774&userName=qyzhg113@core.qyzhg.com"

使用md5做一次加密

# 将字符串使用MD5进行加密
def my_hash(data):
    return MD5.new(data.encode('utf-8'))

将生成的加密数据,再通过rsa的私钥生成签名

# 使用约定的私钥生成签名,注意我这里已经直接调用了md5了
def rsa_sign(data):
    private_key_bytes = base64.b64decode(test_private_key)
    pri_key = RSA.importKey(private_key_bytes)
    signer = PKCS1_v1_5.new(pri_key)
    hash_obj = my_hash(data)
    signature = base64.b64encode(signer.sign(hash_obj))
    return signature

生成的签名结果,

HuCYD1zwCtqUEM2rgFBCVO5gCiDNplaoenArlCA7AGgowXAjiMjCesUuNJZN7I24R+Zq70S2za4Nf7/LfDHa0ajP6rnaA1rXQyhy6ymMzknSAI0Bn9dafmKGCE3fFUt/2e46lGHZFpT3JXgpmEkNczZeMo5iTA+/VKhdGoofOHc=

3.服务器收到你的请求中传递的签名,进行验证签名操作

# 使用约定的公钥验证签名
def rsa_verify(signature, data):
    public_key_bytes = base64.b64decode(test_public_key)
    pub_key = RSA.importKey(public_key_bytes)
    hash_obj = my_hash(data)
    verifier = PKCS1_v1_5.new(pub_key)
    return verifier.verify(hash_obj, base64.b64decode(signature))
test_data = "apiCode=fa4e05682c474619d29cbf3df4a9f69a&entCode=0fe827b0ce0c2f1249642119bc3efcdb&nonce=99999923×tamp=1632747148774&userName=qyzhg113@core.qyzhg.com"
print(rsa_verify(rsa_sign(test_data), test_data))
结果:
True
总结

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/272768.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号