在网站使用支付宝python sdk接入支付后成功后,需要实现用户提现功能,在支付宝沙箱环境下使用sdk顺利实现提现,结果转成正式环境后报错,咨询支付宝客服后告知python sdk不支持提现,原因是提现接口需要证书签名,当时就傻眼了,感觉被支付宝沙箱玩弄了,关键是之前写的支付接口也得重写,最后无奈只能舍弃python sdk自行实现签名和验签请求支付宝接口。下面是自行实现签名和验签全流程:

证书签名需要新加alipay_root_cert_sn和app_cert_sn两个参数,这两个参数需要解析支付宝根证书(alipay_root_cert_sn)和应用公钥证书(appCerPublicKey_"app_id".crt)得到:
import OpenSSL
import re
import rsa
import base64   def sn_string():root_file_li = open(alipayRootCert.crt', 'r').read().split('\n\n')#  支付宝根证书中有4套证书需要一一解析alipay_root_cert_li = []for root_str in root_file_li:cert = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, root_str)certIssue = cert.get_issuer()try:if not re.match(b'sha.+WithRSAEncryption', cert.get_signature_algorithm()):#  只有符合条件的是需要的,4套证书中只有两个有用(具体为啥咱也不太清楚)continueexcept:continueif certIssue.OU:sn_string = 'CN=' + certIssue.CN + ',' + 'OU=' + certIssue.OU + ',' + 'O=' + certIssue.O + ',' + \'C=' + certIssue.C + str(cert.get_serial_number())#  将机构名name和序列号serialNumber按照这样的顺序拼接else:sn_string = 'CN=' + certIssue.CN + ',' + 'O=' + certIssue.O + ',' + 'C=' + certIssue.C + str(cert.get_serial_number())alipay_root_cert_sn = hashlib.md5(sn_string.encode('utf-8')).hexdigest()alipay_root_cert_li.append(alipay_root_cert_sn)alipay_root_cert_sn = '_'.join(alipay_root_cert_li)app_file_str = open(appCertPublicKey_xxxxxxxx.crt', 'r').read()app_cert = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, app_file_str)certIssue = app_cert.get_issuer()app_sn_string = 'CN=' + certIssue.CN + ',' + 'OU=' + certIssue.OU + ',' + 'O=' + certIssue.O + ',' + \'C=' + certIssue.C + str(app_cert.get_serial_number())app_cert_sn = hashlib.md5(app_sn_string.encode('utf-8')).hexdigest()return alipay_root_cert_sn, app_cert_sn
得到alipay_root_cert_sn,app_cert_sn后,加到需要请求接口的参数中进行签名;
def alipay_sign(data_dict):__pem_begin = '-----BEGIN RSA PRIVATE KEY-----\n'__pem_end = '\n-----END RSA PRIVATE KEY-----'def rsa_sign(data_dict, private_key_path):"""SHAWithRSA:param content: 签名内容:type content: str:param private_key: 私钥:type private_key: str:param _hash: hash算法,如:SHA-1,SHA-256:type _hash: str:return: 签名内容:rtype: str"""private_key = _format_private_key(open(private_key_path, 'r').read())pri_key = rsa.PrivateKey.load_pkcs1(private_key.encode('utf-8'))params_list = sorted(data_dict.items(), key=lambda e: e[0], reverse=False)  # 参数字典倒排序为列表params_str = "&".join(u"{}={}".format(k, v) for k, v in params_list)  # 待签名字符串sign_result = rsa.sign(params_str.encode('utf-8'), pri_key, 'SHA-256')return base64.b64encode(sign_result)def _format_private_key(private_key):"""对私进行格式化,缺少"-----BEGIN RSA PRIVATE KEY-----"和"-----END RSA PRIVATE KEY-----"部分需要加上:param private_key: 私钥:return: pem私钥字符串:rtype: str"""if not private_key.startswith(__pem_begin):private_key = __pem_begin + private_keyif not private_key.endswith(__pem_end):private_key = private_key + __pem_endreturn private_keysign = rsa_sign(data_dict, "域名"_私钥.txt')return sign
到这里就已经完成了签名这部分,得到签名sign,将其加到请求接口中的参数“sign”中,这里需要注意的是上面得到的alipay_root_cert_sn,app_cert_sn也要加到请求接口中的参数中支付宝网页支付需要异步验签,异步验签需要用支付宝公钥来验证支付宝传过来的参数和签名。证书签名的情况下支付宝公钥需要解析支付宝公钥证书得到(此处坑太深),下面是实现异步验签流程(这里是在Django下的接口):
def load_alipay_public_key_string():alipay_public_key_cert_string = open(alipayCertPublicKey_RSA2.crt').read()cert = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, alipay_public_key_cert_string)public_key = OpenSSL.crypto.dump_publickey(OpenSSL.crypto.FILETYPE_PEM, cert.get_pubkey()).decode("utf-8")return public_key
def check_alipay(request):alipay_req_dict = request.POST.dict()  # 将传过来的支付宝参数转为普通字典sign = alipay_req_dict.pop('sign')  # 取出传过来的公钥alipay_req_dict.pop('sign_type')  # 去除传过来的sign_typeparams = sorted(alipay_req_dict.items(), key=lambda e: e[0], reverse=False)  # 取出字典元素按key的字母升序排序形成列表message = "&".join(u"{}={}".format(k, v) for k, v in params).encode()  # 将列表转为二进制参数字符串public_key = load_alipay_public_key_string()sign = base64.b64decode(sign)status = bool(rsa.verify(message, sign, rsa.PublicKey.load_pkcs1_openssl_pem(public_key)))  # 或者使用sdk下的verify_with_rsa(public_key, message, sign)  # 验签
验签支付宝密钥签名和证书签名都一样,只是证书签名下支付宝公钥需要解析证书得到

这里不得不吐槽下支付宝文档,自行实现签名全给的是参考java sdk实现,网上证书签名和验签文章也没几篇。这里给大家分享下自己实现的全过程,希望能够避免大家少踩点坑。
最后ps:若是支付宝官方觉得我这篇python自行实现支付宝证书签名和验签可以给用户当做参考的话,拿走不谢,哈哈!!!

python自行实现支付宝证书签名验签全流程相关推荐

  1. 支付宝 php rsa2,#支付宝 RSA2和公钥证书签名验签的区别?

    报错原因 1.密钥不匹配 2.编码格式不统一 3.请求参数数据有误 4.接口调用加签方式和应用上选择的加签方式不对应 5.sdk调用的提交方法有误 6.sdk运行环境有误 排查方案 1.匹配不密钥 ( ...

  2. 工银e生活开发脱坑日志(1)RSA密钥签名验签windows环境下配置

    **环境配置:**阿里云 windows 2012 R2,WAMPSERVER 3.0.17集成环境 **入坑问题:**RSA2密钥对的生产及验签,产生报错信息:Warning: openssl_ve ...

  3. js rsa验签_js rsa sign使用笔记(加密,解密,签名,验签)

    你将会收获: js如何加密, 解密 js如何签名, 验签 js和Java交互如何相互解密, 验签(重点) 通过谷歌, 发现jsrsasign库使用者较多. 查看api发现这个库功能很健全. 本文使用方 ...

  4. 图解PKCS#1——第四部分 签名验签方案

    8.1 RSASSA-PSS签名验签方案 采用EMSA-PSS编码方案 + RSASP/RSAVP签名验签 整个签名/验签流程与加解密流程非常相似. RSASSA-PSS-SIGN (K, M) (§ ...

  5. Python如何接入开放平台?签名验签、加密解密、授权认证测试!

    当前大型top企业都有非常成熟的开放平台业务,比如微信开放平台.新浪微博开放平台.支付宝开放平台等.开放平台的发展为第三方个人或企业提供了巨大的机遇.开发者想要接入各大开放平台,必须要遵从开放平台的安 ...

  6. 学习笔记:公钥私钥 签名验签 加密解密 CA 证书

    重点: 1.区分加密解密和签名验签(在非对称加密情景下) 加密解密:#A给B发消息# A用B的公钥进行运算(加密),B收到后用B自己的私钥进行逆向运算(解密) 签名验签:#A给B发消息# A用A自己的 ...

  7. Windows gmssl生成SM2证书 + java bc库签名验签

    Windows gmssl生成SM2证书 + java bc库签名验签 openssl生成SM2证书 1 生成密钥 gmssl ecparam -genkey -name sm2p256v1 -tex ...

  8. 【可食用】KeyTool生成KeyStore,证书、公钥、私钥文档JAVA生成,JAVA实现ECC签名验签

    KeyTool生成KeyStore,证书.公钥.私钥文档JAVA生成,JAVA实现ECC签名验签 一.首先我们可以写个工具类生成密钥对.证书.公钥.私钥文本 jksAndCerGenerator.ja ...

  9. springboot接口签名统一效验_Python如何接入开放平台?签名验签、加密解密、授权认证测试实战...

    当前大型top企业都有非常成熟的开放平台业务,比如微信开放平台.新浪微博开放平台.支付宝开放平台等.开放平台的发展为第三方个人或企业提供了巨大的机遇.开发者想要接入各大开放平台,必须要遵从开放平台的安 ...

  10. [crypto]-52-python3中rsa(签名验签加密解密)aes(ecb cbc ctr)hmac的使用,以及unittest测试用

    环境: 在ubuntu14.04下,记得安装:sudo pip3 install pycrypto 代码示例1: =========================== import base64 f ...

最新文章

  1. java ee 笔试题目,JSP经典笔试@题目(含答案)
  2. JS验证控制输入中英文字节长度(input、textarea等)
  3. hibernate主配置文件中指定session与当前线程绑定
  4. php正则替换图片地址,求教 php正则把图片地址前部分替换
  5. python——变量的类型、不同类型变量的计算、变量的输入以及格式化输出
  6. java动效_Android 界面漩涡扭曲动效实现
  7. 安装 Anaconda 5.2+python 3.6地址
  8. Linux下内存泄露工具
  9. java 主线程等待_Java实现主线程等待子线程
  10. python通过什么对象连接数据库_Python(十一)数据库连接
  11. 火狐浏览器扩展程序源代码的查看
  12. c语言编程中crol,单片机C语言“_crol_” 与“_cror_”的用法
  13. MySQL-查询本周过生日的人-终极答案
  14. 大数据之足球盘口赔率凯利必发数据采集爬虫
  15. Golang 计算MD5值
  16. FileStore omap的实现
  17. 计算机组成原理 光盘中试题答案,白中英计算机组成原理光盘上试题及答案.doc...
  18. MyBatis总结 Day01
  19. 代码题 10进制转任意进制
  20. 3M年度调查显示,疫情挑战下中国受访者对科学的信任度居全球首位

热门文章

  1. 分块矩阵的逆矩阵的公式记忆方法
  2. 复习330+天,我总结了一份对大多数人都适用的复习经验
  3. 第三阶段应用层——1.5 数码相册—使用FreeType在LCD上显示单个字符
  4. 蓝牙定位听说过的你,知道蓝牙定位信标的存在吗-新导智能
  5. 国内超强JS框架正在开源免费申请中
  6. VM无法获取 vmci 驱动程序版本句柄无效解决办法
  7. SimpleFOC调参1-力矩控制
  8. LoRaWAN节点和网关接入阿里LinkWAN
  9. Linux中rps/rfs的原理及实现
  10. 网页中那些遇到过的导航选中状态actived selected