package com.nova.sankuai.domain.api.xiaobaiyouka; import com.alibaba.fastjson.JSON; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.nova.sankuai.domain.entity.CustomerUser; import com.nova.sankuai.security.HttpClientUtil; import org.apache.commons.codec.binary.Base64; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import java.io.IOException; import java.security.KeyFactory; import java.security.PrivateKey; import java.security.PublicKey; import java.security.Signature; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import java.util.HashMap; import java.util.Map; /** * @Author Lilinhong * @Date 2022/7/26 9:56 */ @Component public class XiaoBaiYouKaUtil { @Value("${xiaobaiyouka.url}") private String url; @Value("${xiaobaiyouka.private-key}") private String privateKey; @Value("${xiaobaiyouka.channel-name}") private String channelName; private static final String KEY_ALGORITHM = "RSA"; public static final String DEFAULT_ALGORITHM = "MD5withRSA"; private static final String DEFAULT_ENCODING = "UTF-8"; private static final Logger logger = LoggerFactory.getLogger("capitalLogger"); private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); public static String sign(String privateKey, String dataSrc) { return sign(privateKey, dataSrc, DEFAULT_ALGORITHM); } /** * 签名 * * @param privateKey:私钥 * @param dataSrc:源 * @param algorithm:签名算法 * @return 签名 */ public static String sign(String privateKey, String dataSrc, String algorithm) { try { PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKey)); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); PrivateKey myPrivateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec); Signature signature = Signature.getInstance(algorithm); signature.initSign(myPrivateKey); signature.update(dataSrc.getBytes(DEFAULT_ENCODING)); byte[] signed = signature.sign(); return Base64.encodeBase64String(signed); } catch (Exception e) { e.printStackTrace(); } return null; } /** * 签名验证 * * @param publicKey:公钥 * @param dataSrc:源 * @param sign:签名结果串 * @return 验签结果 */ public static boolean checkSign(String publicKey, String dataSrc, String sign) throws Exception { X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec( Base64.decodeBase64(publicKey)); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); PublicKey myPublicKey = keyFactory.generatePublic(x509EncodedKeySpec); byte[] signed = Base64.decodeBase64(sign); Signature signature = Signature .getInstance(DEFAULT_ALGORITHM); signature.initVerify(myPublicKey); signature.update(dataSrc.getBytes(DEFAULT_ENCODING)); return signature.verify(signed); } public XiaoBaiYouKaCheckUserResponse checkUser(CustomerUser customerUser) { // 请求体 Map body = new HashMap<>(16); body.put("channel_name", channelName); body.put("mobile_md5", customerUser.getPhoneMd5()); String timestamp = Long.toString(System.currentTimeMillis()); body.put("timestamp", timestamp); String signString = "channelName=" + channelName + "&mobileNumber=" + customerUser.getPhoneMd5() + "×tamp=" + timestamp; try { String sign = sign(privateKey, signString); body.put("sign", sign); } catch (Exception e) { logger.info("手机号为:" + customerUser.getPhone() + ",小白优卡撞库签名失败"); e.printStackTrace(); return null; } String paramString = null; logger.info("手机号为:" + customerUser.getPhone() + ",小白优卡撞库原始数据->:{}", body); try { paramString = OBJECT_MAPPER.writeValueAsString(body); } catch (JsonProcessingException e) { logger.info("手机号为:" + customerUser.getPhone() + ",小白优卡撞库入参序列化后数据错误"); e.printStackTrace(); return null; } String response = null; try { response = HttpClientUtil.getInstance().postJsonData(url + "/jointLogon/checkUser", paramString); logger.info("手机号为:" + customerUser.getPhone() + ",小白优卡撞库原始返回数据->:{}", response); } catch (IOException e) { logger.error("手机号为:" + customerUser.getPhone() + ",小白优卡撞库原始返回数据失败->:{}", response); e.printStackTrace(); return null; } if (StringUtils.isEmpty(response)) { logger.error("手机号为:" + customerUser.getPhone() + ",小白优卡撞库返回数据失败为空"); return null; } XiaoBaiYouKaCheckUserResponse xiaoBaiYouKaCheckUserResponse = null; try { xiaoBaiYouKaCheckUserResponse = JSON.parseObject(response, XiaoBaiYouKaCheckUserResponse.class); } catch (Exception e) { logger.error("手机号为:" + customerUser.getPhone() + ",小白优卡撞库原始返回数据转换失败->:{}", xiaoBaiYouKaCheckUserResponse); e.printStackTrace(); return null; } return xiaoBaiYouKaCheckUserResponse; } public XiaoBaiYouKaRegisterResponse register(CustomerUser customerUser) { // 请求体 Map body = new HashMap<>(16); body.put("channel_name", channelName); body.put("mobile", customerUser.getPhone()); String timestamp = Long.toString(System.currentTimeMillis()); body.put("timestamp", timestamp); String signString = "channelName=" + channelName + "&mobileNumber=" + customerUser.getPhone() + "×tamp=" + timestamp; try { String sign = sign(privateKey, signString); body.put("sign", sign); } catch (Exception e) { logger.info("手机号为:" + customerUser.getPhone() + ",小白优卡联登签名失败"); e.printStackTrace(); return null; } String paramString = null; logger.info("手机号为:" + customerUser.getPhone() + ",小白优卡联登原始数据->:{}", body); try { paramString = OBJECT_MAPPER.writeValueAsString(body); } catch (JsonProcessingException e) { logger.info("手机号为:" + customerUser.getPhone() + ",小白优卡联登入参序列化后数据错误"); e.printStackTrace(); return null; } String response = null; try { response = HttpClientUtil.getInstance().postJsonData(url + "/jointLogon/register", paramString); logger.info("手机号为:" + customerUser.getPhone() + ",小白优卡联登原始返回数据->:{}", response); } catch (IOException e) { logger.error("手机号为:" + customerUser.getPhone() + ",小白优卡联登原始返回数据失败->:{}", response); e.printStackTrace(); return null; } if (StringUtils.isEmpty(response)) { logger.error("手机号为:" + customerUser.getPhone() + ",小白优卡联登返回数据失败为空"); return null; } XiaoBaiYouKaRegisterResponse xiaoBaiYouKaRegisterResponse = null; try { xiaoBaiYouKaRegisterResponse = JSON.parseObject(response, XiaoBaiYouKaRegisterResponse.class); } catch (Exception e) { logger.error("手机号为:" + customerUser.getPhone() + ",小白优卡联登原始返回数据转换失败->:{}", xiaoBaiYouKaRegisterResponse); e.printStackTrace(); return null; } return xiaoBaiYouKaRegisterResponse; } }