You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
BookStore/src/com/yj/utils/PaymentUtil.java

215 lines
7.1 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

package com.yj.utils;
/**
* @author yj
* @create 2020-08-30 9:00
*/
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
public class PaymentUtil {
// 定义字符编码
private static String encodingCharset = "UTF-8";
/**
* 生成hmac方法用于构建支付请求的参数签名
*
* @param p0_Cmd 业务类型
* @param p1_MerId 商户编号
* @param p2_Order 商户订单号
* @param p3_Amt 支付金额
* @param p4_Cur 交易币种
* @param p5_Pid 商品名称
* @param p6_Pcat 商品种类
* @param p7_Pdesc 商品描述
* @param p8_Url 商户接收支付成功数据的地址
* @param p9_SAF 送货地址
* @param pa_MP 商户扩展信息
* @param pd_FrpId 银行编码
* @param pr_NeedResponse 应答机制
* @param keyValue 商户密钥
* @return 生成的hmac签名
*/
public static String buildHmac(String p0_Cmd, String p1_MerId,
String p2_Order, String p3_Amt, String p4_Cur, String p5_Pid, String p6_Pcat,
String p7_Pdesc, String p8_Url, String p9_SAF, String pa_MP, String pd_FrpId,
String pr_NeedResponse, String keyValue) {
StringBuilder sValue = new StringBuilder();
// 依次追加所有参数到StringBuilder
sValue.append(p0_Cmd);
sValue.append(p1_MerId);
sValue.append(p2_Order);
sValue.append(p3_Amt);
sValue.append(p4_Cur);
sValue.append(p5_Pid);
sValue.append(p6_Pcat);
sValue.append(p7_Pdesc);
sValue.append(p8_Url);
sValue.append(p9_SAF);
sValue.append(pa_MP);
sValue.append(pd_FrpId);
sValue.append(pr_NeedResponse);
// 调用hmacSign方法生成签名
return PaymentUtil.hmacSign(sValue.toString(), keyValue);
}
/**
* 验证支付网关回调的hmac签名
*
* @param hmac 支付网关发来的加密验证码
* @param p1_MerId 商户编号
* @param r0_Cmd 业务类型
* @param r1_Code 支付结果
* @param r2_TrxId 易宝支付交易流水号
* @param r3_Amt 支付金额
* @param r4_Cur 交易币种
* @param r5_Pid 商品名称
* @param r6_Order 商户订单号
* @param r7_Uid 易宝支付会员ID
* @param r8_MP 商户扩展信息
* @param r9_BType 交易结果返回类型
* @param keyValue 密钥
* @return 验证结果true表示验证通过
*/
public static boolean verifyCallback(String hmac, String p1_MerId,
String r0_Cmd, String r1_Code, String r2_TrxId, String r3_Amt,
String r4_Cur, String r5_Pid, String r6_Order, String r7_Uid,
String r8_MP, String r9_BType, String keyValue) {
StringBuilder sValue = new StringBuilder();
// 依次追加所有回调参数到StringBuilder
sValue.append(p1_MerId);
sValue.append(r0_Cmd);
sValue.append(r1_Code);
sValue.append(r2_TrxId);
sValue.append(r3_Amt);
sValue.append(r4_Cur);
sValue.append(r5_Pid);
sValue.append(r6_Order);
sValue.append(r7_Uid);
sValue.append(r8_MP);
sValue.append(r9_BType);
// 调用hmacSign方法生成签名并与支付网关的签名比较
String sNewString = PaymentUtil.hmacSign(sValue.toString(), keyValue);
return sNewString.equals(hmac);
}
/**
* 使用HMAC-MD5算法生成签名
*
* @param aValue 待签名的字符串
* @param aKey 密钥
* @return 生成的签名
*/
public static String hmacSign(String aValue, String aKey) {
// 初始化内部填充字节数组
byte k_ipad[] = new byte[64];
byte k_opad[] = new byte[64];
byte keyb[];
byte value[];
try {
// 使用指定的字符编码获取字节数组
keyb = aKey.getBytes(encodingCharset);
value = aValue.getBytes(encodingCharset);
} catch (UnsupportedEncodingException e) {
// 如果不支持指定的字符编码,则使用默认字符编码
keyb = aKey.getBytes();
value = aValue.getBytes();
}
// 填充k_ipad和k_opad数组
Arrays.fill(k_ipad, keyb.length, 64, (byte) 54);
Arrays.fill(k_opad, keyb.length, 64, (byte) 92);
for (int i = 0; i < keyb.length; i++) {
k_ipad[i] = (byte) (keyb[i] ^ 0x36);
k_opad[i] = (byte) (keyb[i] ^ 0x5c);
}
// 获取MD5算法的MessageDigest实例
MessageDigest md = null;
try {
md = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException e) {
// 如果MD5算法不可用则返回null
return null;
}
// 对k_ipad和待签名数据进行更新
md.update(k_ipad);
md.update(value);
byte dg[] = md.digest(); // 进行第一次摘要
md.reset(); // 重置MessageDigest实例
// 对k_opad和第一次摘要结果进行更新
md.update(k_opad);
md.update(dg, 0, 16);
dg = md.digest(); // 进行第二次摘要,得到最终的签名
return toHex(dg); // 将字节数组转换为十六进制字符串
}
/**
* 将字节数组转换为十六进制字符串
*
* @param input 字节数组
* @return 十六进制字符串
*/
public static String toHex(byte input[]) {
if (input == null)
return null;
StringBuffer output = new StringBuffer(input.length * 2);
for (int i = 0; i < input.length; i++) {
int current = input[i] & 0xff;
if (current < 16)
output.append("0");
output.append(Integer.toString(current, 16));
}
return output.toString();
}
/**
* 根据参数数组和密钥生成HMAC签名
*
* @param args 参数数组
* @param key 密钥
* @return 生成的HMAC签名
*/
public static String getHmac(String[] args, String key) {
if (args == null || args.length == 0) {
return (null);
}
StringBuffer str = new StringBuffer();
for (int i = 0; i < args.length; i++) {
str.append(args[i]);
}
return (hmacSign(str.toString(), key));
}
/**
* 使用SHA算法对字符串进行摘要
*
* @param aValue 待摘要的字符串
* @return 摘要结果的十六进制字符串
*/
public static String digest(String aValue) {
aValue = aValue.trim();
byte value[];
try {
value = aValue.getBytes(encodingCharset);
} catch (UnsupportedEncodingException e) {
value = aValue.getBytes();
}
MessageDigest md = null;
try {
md = MessageDigest.getInstance("SHA");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
return null;
}
return toHex(md.digest(value));
}
}