和第三方对接加密,通常需要进行字段加密,再进行传输。
1.XML排序后加密
项目实践中,和百年保险对接使用到了这种加密
import xmltodict
import hashlib
from lxml import etree
# 计算加密串
def xml_sorting_sha256(xml_str, secret_str):
"""
插入xml字符串,返回排序好后并且加密的串
排序规则为
按字母升序排序后加上加密密钥secret,进行SHA-256加密
"""
# 排序
doc = etree.XML(xml_str, etree.XMLParser(remove_blank_text=True))
for parent in doc.xpath('//*[./*]'): # Search for parent elements
parent[:] = sorted(parent, key=lambda x: x.tag)
a = etree.tounicode(doc)
to_xml = xmltodict.unparse(xmltodict.parse(a), short_empty_elements=False)[39:]
# 加密
to_secret = to_xml + secret_str
s = hashlib.sha256()
s.update(to_secret.encode("utf8"))
to_string = s.hexdigest()
# 返回加密串 和 排序后的xml
return to_string, to_xml
2.json拼接后加密
在项目实践中,阿里云,微信等接口对接会用到这种加密方式
import hashlib
# 签名生成
def generate_sign(params, key):
"""
params: 参数,dict 对象
key: API 密钥
"""
param_list = []
for k in sorted(params.keys()):
v = params.get(k)
if not v:
# 参数的值为空不参与签名
continue
param_list.append('{0}={1}'.format(k, v))
# 在最后拼接 key
param_list.append('key={}'.format(key))
# 用 & 连接各 k-v 对,然后对字符串进行 MD5 运算
return (hashlib.md5('&'.join(param_list).encode('utf8')).hexdigest()).upper()