package ZhimaCertify import ( "encoding/json" "errors" "net/url" "gitea.ddegame.cn/open/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 }