package com.ishop.mobile.util; import com.fasterxml.jackson.databind.node.ObjectNode; import com.iplatform.base.PlatformRuntimeException; import com.iplatform.base.WechatConstants; import com.iplatform.core.util.AESUtils; import com.walker.infrastructure.utils.JsonUtils; import com.walker.infrastructure.utils.MD5; import com.walker.infrastructure.utils.StringUtils; import org.apache.commons.codec.binary.Base64; import org.apache.commons.codec.digest.DigestUtils; import java.security.InvalidAlgorithmParameterException; import java.text.MessageFormat; import java.util.Arrays; import java.util.Map; import java.util.Set; public class WechatUtils { public static final String JS_SIGN = "jsapi_ticket={0}&noncestr={1}×tamp={2}&url={3}"; private static final String WATERMARK = "watermark"; private static final String APPID = "appid"; /** * 解密微信手机号。 * @param miniAppId * @param encryptData * @param sessionKey * @param iv * @return * @date 2023-09-15 */ public static final String decryptPhoneNumber(String miniAppId, String encryptData, String sessionKey, String iv){ String result = StringUtils.EMPTY_STRING; try { byte[] decryptByte = AESUtils.decrypt(Base64.decodeBase64(encryptData), Base64.decodeBase64(sessionKey), Base64.decodeBase64(iv)); if(decryptByte == null || decryptByte.length == 0){ return result; } result = new String(WxPKCS7Encoder.decode(decryptByte)); // JSONObject jsonObject = JSONObject.parseObject(result); // String decryptAppid = jsonObject.getJSONObject(WATERMARK).getString(APPID); // if(!appId.equals(decryptAppid)){ // result = ""; // } return result; } catch (InvalidAlgorithmParameterException e) { throw new RuntimeException("解密微信手机号错误:" + e.getMessage(), e); } } public static final String getWechatOauthAccessTokenUrl(String appId, String secret, String code){ return MessageFormat.format(WechatConstants.WECHAT_OAUTH2_ACCESS_TOKEN_URL, appId, secret, code); } /** * 获取ticket时,生成签名信息。 * @param nonceStr * @param ticket * @param timestamp * @param url * @return * @date 2023-07-16 * @date 2023-07-25 timestamp必须用字符串形式,否则格式化会默认转为金额(逗号分隔)形式。 */ public static String getJsSdkSign(String nonceStr, String ticket, String timestamp, String url){ String data = MessageFormat.format(JS_SIGN, ticket, nonceStr, timestamp, url); return DigestUtils.sha1Hex(data); } /** * 获取sign * @param voJson 微信公共下单对象 * @param signKey 微信签名key * @return String */ public static String getSign(String voJson, String signKey) throws Exception { // 对象转map Map map = JsonUtils.jsonStringToObject(voJson, Map.class); // map排序 Set keySet = map.keySet(); String[] keyArray = keySet.toArray(new String[keySet.size()]); Arrays.sort(keyArray); StringBuilder sb = new StringBuilder(); for (String k : keyArray) { if (k.equals(MD5.NAME_SIGN_2)) { continue; } // 参数值为空,则不参与签名 if (map.get(k) != null && StringUtils.isNotEmpty(map.get(k).toString())){ sb.append(k).append("=").append(map.get(k)).append("&"); } } sb.append("key=").append(signKey); String sign = DigestUtils.sha1Hex(sb.toString()).toUpperCase(); System.out.println("sign ========== " + sign); return sign; } /** * 获取sign * @param map 待签名数据 * @param signKey 微信签名key * @return String */ public static String getSign(Map map, String signKey) throws Exception{ // map排序 Set keySet = map.keySet(); String[] keyArray = keySet.toArray(new String[keySet.size()]); Arrays.sort(keyArray); StringBuilder sb = new StringBuilder(); for (String k : keyArray) { if (k.equals(MD5.NAME_SIGN_2)) { continue; } if (StringUtils.isNotEmpty(map.get(k)) && map.get(k).trim().length() > 0) // 参数值为空,则不参与签名 sb.append(k).append("=").append(map.get(k).trim()).append("&"); } sb.append("key=").append(signKey); // String sign = SecureUtil.md5(sb.toString()).toUpperCase(); String sign = MD5.getMessageDigest(sb.toString().getBytes(StringUtils.DEFAULT_CHARSET_UTF8)).toUpperCase(); System.out.println("sign ========== " + sign); return sign; } public static final ObjectNode acquireObjectNode(String entity){ ObjectNode objectNode = null; try { objectNode = JsonUtils.jsonStringToObjectNode(entity); } catch (Exception e) { throw new PlatformRuntimeException("string转ObjectNode错误:" + e.getMessage(), e); } return objectNode; } }