213 lines
7.0 KiB
Go
213 lines
7.0 KiB
Go
package ZhimaCertify
|
||
|
||
import (
|
||
"encoding/json"
|
||
"errors"
|
||
"net/url"
|
||
"servicebase/pkg/htools"
|
||
|
||
"github.com/anxpp/beego/logs"
|
||
)
|
||
|
||
// 芝麻认证SDK
|
||
type ZhimaCertifyClient struct {
|
||
GatewayUrl string
|
||
AppId string
|
||
PublicKey string
|
||
PrivateKey string
|
||
}
|
||
|
||
// 芝麻开放平台的key
|
||
const (
|
||
// 蚂蚁开放平台 https://openapi.alipay.com/gateway.do
|
||
// 芝麻信用api https://zmopenapi.zmxy.com.cn/openapi.do
|
||
ZHIMA_MERCHANT_ID = "268282100002002118952271"
|
||
ZHIMA_CERTIFY_GATEWAY_URL = "https://zmopenapi.zmxy.com.cn/openapi.do" // 网关
|
||
|
||
ZHIMA_CERTIFY_APP_ID = "30000229371" // APPID
|
||
|
||
// 芝麻公钥
|
||
ZHIMA_CERTIFY_PUBLIC_KEY = `
|
||
-----BEGIN PUBLIC KEY-----
|
||
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQK22BgQCNunjjn51b3XUnsTXGa6C3dBnA
|
||
U7UP1FCxJN4T1CIxCC5I+Fi9lrzFy899g224JzcTywePp3jIg4aG/11qIJS2edkTUo
|
||
7XM8qxpl+ApaRoCLx4NezDzOxVSGYqnu2295wnKW/ft3T+aZQwgELw60IrVutFMOKr1
|
||
H7yrrzbar/OrgaOxLQIDAQAB
|
||
-----END PUBLIC KEY-----
|
||
`
|
||
// 商户私钥
|
||
ZHIMA_CERTIFY_PRIVATE_KEY = `
|
||
-----BEGIN RSA PRIVATE KEY-----
|
||
MIICWwIBAAKBgQDHbe15atuwmQaIUiX9kx45T22dRDmfYz7+rIoQCjR3+J2AQkMX1g3
|
||
9BQZfRJyN8/31GD98zjZr0KowxFYnDJC422w+6mnAtY63fJW32VvIqTbz7PHF/iyVE0
|
||
WCWu2IlukzljaZFg6SK2SD5+ROQEYL3dhzg87/4iDvDIBKuK222HftTMPvLcwIDAQAB
|
||
AoGAREH0uM0BOnV1zezIAf17p8NitmyY3v22fr1RV+IWSUWzEWhryPdj289LegoCx3d
|
||
OYbgV6sKtz8MQrTZWAnGDiynMe1yucNIRCsq1b0rCoMFGo52vFidYKH2SeGnRKQcMq
|
||
6lohM+ialbwabDJW8eFBq6jqm+3KcIPyETmpcBLIawX0c21ECQQDotn2hHOTo0IHsx
|
||
oxtwA3i8u0OL8dGbrOyBL5xYVRpxas2Sry9WcCLuDCC52VNKszQq+W2xTPriqvuv/V
|
||
rBvrtGxLAkEA22LR0G9PNHGIg2K6+lcQWZ8F53cO32cSP3pKfO6A2m2wzii2mPViU6
|
||
ONlTJKAB3VlHn13XVxVcaFhdfwcxLARUeQJABq3eC+VH22l2FrR8RvsCpZV8lkKesZ
|
||
4gb3jsmoChz/MkwndFNU330+c2ijs84Mces8qLQC22h+du0DZky2QyNPSruwJAPpeB
|
||
GSDIzkOeGS4v/oCcj5VJT/Kt8SPFkFDw0UgyjCY22u9GuXk5JnfBS1HfvwzEBOqO9T
|
||
IutbRAICGt3ob5CEsQJABLSmUBbUmbILI0ymD9AFmX11t1mijZFnC1X22I5kR4TM511
|
||
Oe3j6CFhvyXOg0L9jXKMxcD7GJN73PkglcVypxbzqg==
|
||
-----END RSA PRIVATE KEY-----
|
||
`
|
||
|
||
ZHIMA_CERTIFY_CHARSET = "UTF-8" // 编码
|
||
ZHIMA_CERTIFY_PRODUCT_CODE = "w1010100000000002978" // 固定值
|
||
)
|
||
|
||
func NewZhimaCertifyClient() *ZhimaCertifyClient {
|
||
return &ZhimaCertifyClient{GatewayUrl: ZHIMA_CERTIFY_GATEWAY_URL, AppId: ZHIMA_CERTIFY_APP_ID, PublicKey: ZHIMA_CERTIFY_PUBLIC_KEY, PrivateKey: ZHIMA_CERTIFY_PRIVATE_KEY}
|
||
}
|
||
|
||
// 芝麻认证系统参数
|
||
/*
|
||
每个接口文档中详细定义了接口业务参数列表,业务参数本身是通过系统参数params发送到服务器端的。这里主要描述这些业务参数是以什么格式组合,并拼装成了系统参数params的。假设接口A定义了两个业务参数,param1和param2,值分别为param1_value和param2_value。系统参数params和业务参数的关系为:params= URLEncode (Base64(RSAEncrypt(param1=URLEncode(param1_value) & param2=URLEncode(param2_value))))。
|
||
首先对于每个业务参数,先进行一次URLEncode,然后按照URL中传递参数的方式把param1和param2拼接起来(使用&和=号)
|
||
然后对拼接起来的业务参数进行RSA的加密,得到byte数组
|
||
然后对RSA加密后得到byte数组进行Base64编码
|
||
最后对Base64编码后的params参数做一次URLEncode,URLEncode后的值最终组成了系统参数params的值
|
||
*/
|
||
|
||
// 芝麻认证初始化
|
||
func (s *ZhimaCertifyClient) ZhimaCertifyInit(certifyId, certNo, trueName string) (result string, err error) {
|
||
|
||
// 方法名
|
||
method := "zhima.customer.certification.initialize"
|
||
// 业务参数
|
||
certMap := make(map[string]string, 0)
|
||
certMap["identity_type"] = "CERT_INFO"
|
||
certMap["cert_type"] = "IDENTITY_CARD"
|
||
certMap["cert_name"] = trueName
|
||
certMap["cert_no"] = certNo
|
||
|
||
certMapByte, _ := json.Marshal(certMap)
|
||
|
||
bizMap := make(map[string]string, 0)
|
||
bizMap["transaction_id"] = certifyId
|
||
bizMap["product_code"] = ZHIMA_CERTIFY_PRODUCT_CODE
|
||
bizMap["biz_code"] = "FACE_SDK"
|
||
bizMap["identity_param"] = string(certMapByte)
|
||
//bizMap["merchant_config"] = `{"need_user_authorization":"false"}`
|
||
|
||
// 请求参数
|
||
requestParam := getCertifyRequestParams(method, bizMap)
|
||
|
||
headerMap := make(map[string]string, 0)
|
||
|
||
logs.Error("初始化芝麻信用API request:" + requestParam)
|
||
|
||
url := ZHIMA_CERTIFY_GATEWAY_URL + "?" + requestParam
|
||
responseBody, httpErr := htools.HttpDo("GET", url, headerMap, "")
|
||
|
||
logs.Debug("初始化芝麻信用 response:" + responseBody)
|
||
|
||
if httpErr != nil {
|
||
err = httpErr
|
||
logs.Error("初始化芝麻信用失败:" + httpErr.Error())
|
||
return
|
||
}
|
||
|
||
result = responseBody
|
||
return
|
||
}
|
||
|
||
// 芝麻认证查询结果
|
||
func (s *ZhimaCertifyClient) ZhimaCertifyQueryResult(bizNo string) (result string, err error) {
|
||
// 方法名
|
||
method := "zhima.customer.certification.query"
|
||
// 业务参数
|
||
bizMap := map[string]string{"biz_no": bizNo}
|
||
|
||
// 请求参数
|
||
requestParam := getCertifyRequestParams(method, bizMap)
|
||
|
||
if len(requestParam) == 0 {
|
||
logs.Info("请求参数为空")
|
||
err = errors.New("请求参数错误")
|
||
return
|
||
}
|
||
headerMap := make(map[string]string, 0)
|
||
url := ZHIMA_CERTIFY_GATEWAY_URL + "?" + requestParam
|
||
responseBody, httpErr := htools.HttpDo("GET", url, headerMap, "")
|
||
|
||
if httpErr != nil {
|
||
err = httpErr
|
||
return
|
||
}
|
||
|
||
result = responseBody
|
||
|
||
return
|
||
|
||
}
|
||
|
||
// 获取芝麻认证请求参数
|
||
func getCertifyRequestParams(method string, bizMap map[string]string) string {
|
||
|
||
// 系统参数转请求
|
||
sysMap := make(map[string]string, 0)
|
||
sysMap["app_id"] = url.QueryEscape(ZHIMA_CERTIFY_APP_ID)
|
||
sysMap["charset"] = url.QueryEscape(ZHIMA_CERTIFY_CHARSET)
|
||
sysMap["method"] = url.QueryEscape(method)
|
||
sysMap["platform"] = url.QueryEscape("zmop")
|
||
sysMap["version"] = url.QueryEscape("1.0")
|
||
|
||
// 待签名的参数
|
||
waitSignParam := getNotEncryptBizParam(bizMap)
|
||
|
||
logs.Error("待签名参数:" + waitSignParam)
|
||
// 签名
|
||
sign, signErr := htools.RsaSHA1Sign(waitSignParam, ZHIMA_CERTIFY_PRIVATE_KEY)
|
||
|
||
logs.Error("签名:" + sign)
|
||
|
||
if signErr != nil {
|
||
logs.Error("签名失败" + signErr.Error())
|
||
return ""
|
||
}
|
||
sysMap["sign"] = url.QueryEscape(sign)
|
||
|
||
// 获取加密过的业务参数
|
||
params := getCertifyBizParams(bizMap)
|
||
sysMap["params"] = params
|
||
logs.Error("加密过的业务参数:" + params)
|
||
|
||
sysParams := htools.MapToUrlParams(sysMap)
|
||
|
||
return sysParams
|
||
}
|
||
|
||
// 获取芝麻认证业务参数
|
||
func getCertifyBizParams(bizMap map[string]string) string {
|
||
|
||
//1. 首先对于每个业务参数,先进行一次 URLEncode,然后按照 URL 中传递参数的方式把 param1 和 param2 拼接起来(使用 & 和 = 号)然后对拼接起来的业务参数进行 RSA 的加密,得到 byte 数组
|
||
|
||
urlParams := getNotEncryptBizParam(bizMap)
|
||
//urlParams := "1"
|
||
//RSA加密
|
||
paramByte, _ := htools.RsaEncrypt(urlParams, ZHIMA_CERTIFY_PUBLIC_KEY)
|
||
|
||
//2. 然后对 RSA 加密后得到 byte 数组进行 Base64 编码
|
||
base64Param := paramByte
|
||
|
||
//3. 最后对 Base64 编码后的 params 参数做一次 URLEncode,URLEncode 后的值最终组成了系统参数 params 的值
|
||
|
||
return url.QueryEscape(base64Param)
|
||
}
|
||
|
||
// 获取未加密的业务参数
|
||
func getNotEncryptBizParam(bizMap map[string]string) string {
|
||
|
||
mapData := make(map[string]string, 0)
|
||
for k, v := range bizMap {
|
||
mapData[k] = url.QueryEscape(v)
|
||
}
|
||
|
||
urlParams := htools.MapToUrlParams(mapData)
|
||
|
||
return urlParams
|
||
}
|