接口签名参数排序

1、待发送报文各字段的键(Key)按照字符串的字典顺序排序。如果字段为复合数据类型,按如下规则处理:如果数据类型是 List ,则对字段名按照字符串字典顺序排序

2、 从排序好的报文中依次取出各字段的值(Value),依次拼接起来;
3、计算整个拼接好的字符串的 MD5 值,转换为 16 进制的字符串,并赋值
给 sign 字段
 

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@SuppressWarnings("all")
public class ParameterOrdering {
	
	public static void main(String[] args) {
        // 测试数据
		School s = new School();
		s.setId("111122222");
		s.setAddress("北京");
		
		Section se = new Section();
		se.setId("33326666");
		se.setName("数学");
		se.setRs(86);
		List<Section> sectionList = new ArrayList<>();
		sectionList.add(se);
		s.setSectionList(sectionList);
        // 签名
		String paramOrder = generateSign(s);
	}
	
	public static String generateSign(Object data){
		Field[] fields = data.getClass().getDeclaredFields();
		List<Field> allFields = new ArrayList<>();
		Class supperclass = data.getClass().getSuperclass();
		while(supperclass != null){
			allFields.addAll(Arrays.asList(supperclass.getDeclaredFields()));
			supperclass =supperclass.getSuperclass();
		}
		allFields.addAll(Arrays.asList(fields));
		allFields.sort(new FieldComparator());
		StringBuilder stringBuilder =new StringBuilder();
		try{
			for(Field field:allFields){
				stringBuilder.append(getValue(field,data));
			}
		}catch(Exception e){
			e.printStackTrace();
			throw new RuntimeException(e);
		}
		System.out.println("Json 报文中各字段排序后取得的值拼接:"+stringBuilder.toString());
		return Digestutils.md5Hex(stringBuilder.toString());
	}

	public static String getValue(Field field, Object o) throws Exception {
		field.setAccessible(true);
		if (o == null || field.get(o) == null) {
			return "";
		}
		Object value = field.get(o);
		if (value.getClass().getName().startsWith("java.lang")) {
			return String.valueOf(field.get(o));
		} else if (value instanceof List) {
			List list = (List) value;
			StringBuilder stringBuilder = new StringBuilder();
			for (Object object : list) {
				if (object.getClass().getName().startsWith("java.lang")) {
					stringBuilder.append(object);
				} else {
					Field[] fields = object.getClass().getDeclaredFields();
					List<Field> fieldList = Arrays.asList(fields);
					fieldList.sort(new FieldComparator());
					for (Field f : fieldList) {
						stringBuilder.append(getValue(f, object));
					}

				}
			}
			return stringBuilder.toString();
		} else {
			Field[] fields = field.get(o).getClass().getDeclaredFields();
			List<Field> allFields = Arrays.asList(fields);
			allFields.sort(new FieldComparator());
			StringBuilder stringBuilder = new StringBuilder();
			for (Field f : allFields) {
				f.setAccessible(true);
				if (f.get(field.get(o)) != null) {
					stringBuilder.append(getValue(f, field.get(o)));
				}
			}
			return stringBuilder.toString();
		}
	}
	
	private static class FieldComparator implements Comparator<Field> {
		public int compare(Field a, Field b) {
			 return a.getName().compareTo(b.getName());
		}
		
	}
}
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.codec.binary.StringUtils;

public class Digestutils {
	private static final int STREAM_BUFFER_LENGTH = 1024;
	private final MessageDigest messageDigest;

	public static byte[] digest(MessageDigest messageDigest, byte[] data) {
		return messageDigest.digest(data);
	}

	public static byte[] digest(MessageDigest messageDigest, ByteBuffer data) {
		messageDigest.update(data);
		return messageDigest.digest();
	}

	public static byte[] digest(MessageDigest messageDigest, File data) throws IOException {
		return updateDigest(messageDigest, data).digest();
	}

	public static byte[] digest(MessageDigest messageDigest, InputStream data) throws IOException {
		return updateDigest(messageDigest, data).digest();
	}

	public static MessageDigest getDigest(String algorithm) {
		try {
			return MessageDigest.getInstance(algorithm);
		} catch (NoSuchAlgorithmException var2) {
			throw new IllegalArgumentException(var2);
		}
	}

	public static MessageDigest getDigest(String algorithm, MessageDigest defaultMessageDigest) {
		try {
			return MessageDigest.getInstance(algorithm);
		} catch (Exception var3) {
			return defaultMessageDigest;
		}
	}

	public static MessageDigest getMd2Digest() {
		return getDigest("MD2");
	}

	public static MessageDigest getMd5Digest() {
		return getDigest("MD5");
	}

	public static MessageDigest getSha1Digest() {
		return getDigest("SHA-1");
	}

	public static MessageDigest getSha256Digest() {
		return getDigest("SHA-256");
	}

	public static MessageDigest getSha384Digest() {
		return getDigest("SHA-384");
	}

	public static MessageDigest getSha512Digest() {
		return getDigest("SHA-512");
	}

	/** @deprecated */
	@Deprecated
	public static MessageDigest getShaDigest() {
		return getSha1Digest();
	}

	public static byte[] md2(byte[] data) {
		return getMd2Digest().digest(data);
	}

	public static byte[] md2(InputStream data) throws IOException {
		return digest(getMd2Digest(), data);
	}

	public static byte[] md2(String data) {
		return md2(StringUtils.getBytesUtf8(data));
	}

	public static String md2Hex(byte[] data) {
		return Hex.encodeHexString(md2(data));
	}

	public static String md2Hex(InputStream data) throws IOException {
		return Hex.encodeHexString(md2(data));
	}

	public static String md2Hex(String data) {
		return Hex.encodeHexString(md2(data));
	}

	public static byte[] md5(byte[] data) {
		return getMd5Digest().digest(data);
	}

	public static byte[] md5(InputStream data) throws IOException {
		return digest(getMd5Digest(), data);
	}

	public static byte[] md5(String data) {
		return md5(StringUtils.getBytesUtf8(data));
	}

	public static String md5Hex(byte[] data) {
		return Hex.encodeHexString(md5(data));
	}

	public static String md5Hex(InputStream data) throws IOException {
		return Hex.encodeHexString(md5(data));
	}

	public static String md5Hex(String data) {
		return Hex.encodeHexString(md5(data));
	}

	/** @deprecated */
	@Deprecated
	public static byte[] sha(byte[] data) {
		return sha1(data);
	}

	/** @deprecated */
	@Deprecated
	public static byte[] sha(InputStream data) throws IOException {
		return sha1(data);
	}

	/** @deprecated */
	@Deprecated
	public static byte[] sha(String data) {
		return sha1(data);
	}

	public static byte[] sha1(byte[] data) {
		return getSha1Digest().digest(data);
	}

	public static byte[] sha1(InputStream data) throws IOException {
		return digest(getSha1Digest(), data);
	}

	public static byte[] sha1(String data) {
		return sha1(StringUtils.getBytesUtf8(data));
	}

	public static String sha1Hex(byte[] data) {
		return Hex.encodeHexString(sha1(data));
	}

	public static String sha1Hex(InputStream data) throws IOException {
		return Hex.encodeHexString(sha1(data));
	}

	public static String sha1Hex(String data) {
		return Hex.encodeHexString(sha1(data));
	}

	public static byte[] sha256(byte[] data) {
		return getSha256Digest().digest(data);
	}

	public static byte[] sha256(InputStream data) throws IOException {
		return digest(getSha256Digest(), data);
	}

	public static byte[] sha256(String data) {
		return sha256(StringUtils.getBytesUtf8(data));
	}

	public static String sha256Hex(byte[] data) {
		return Hex.encodeHexString(sha256(data));
	}

	public static String sha256Hex(InputStream data) throws IOException {
		return Hex.encodeHexString(sha256(data));
	}

	public static String sha256Hex(String data) {
		return Hex.encodeHexString(sha256(data));
	}

	public static byte[] sha384(byte[] data) {
		return getSha384Digest().digest(data);
	}

	public static byte[] sha384(InputStream data) throws IOException {
		return digest(getSha384Digest(), data);
	}

	public static byte[] sha384(String data) {
		return sha384(StringUtils.getBytesUtf8(data));
	}

	public static String sha384Hex(byte[] data) {
		return Hex.encodeHexString(sha384(data));
	}

	public static String sha384Hex(InputStream data) throws IOException {
		return Hex.encodeHexString(sha384(data));
	}

	public static String sha384Hex(String data) {
		return Hex.encodeHexString(sha384(data));
	}

	public static byte[] sha512(byte[] data) {
		return getSha512Digest().digest(data);
	}

	public static byte[] sha512(InputStream data) throws IOException {
		return digest(getSha512Digest(), data);
	}

	public static byte[] sha512(String data) {
		return sha512(StringUtils.getBytesUtf8(data));
	}

	public static String sha512Hex(byte[] data) {
		return Hex.encodeHexString(sha512(data));
	}

	public static String sha512Hex(InputStream data) throws IOException {
		return Hex.encodeHexString(sha512(data));
	}

	public static String sha512Hex(String data) {
		return Hex.encodeHexString(sha512(data));
	}

	/** @deprecated */
	@Deprecated
	public static String shaHex(byte[] data) {
		return sha1Hex(data);
	}

	/** @deprecated */
	@Deprecated
	public static String shaHex(InputStream data) throws IOException {
		return sha1Hex(data);
	}

	/** @deprecated */
	@Deprecated
	public static String shaHex(String data) {
		return sha1Hex(data);
	}

	public static MessageDigest updateDigest(MessageDigest messageDigest, byte[] valueToDigest) {
		messageDigest.update(valueToDigest);
		return messageDigest;
	}

	public static MessageDigest updateDigest(MessageDigest messageDigest, ByteBuffer valueToDigest) {
		messageDigest.update(valueToDigest);
		return messageDigest;
	}

	public static MessageDigest updateDigest(MessageDigest digest, File data) throws IOException {
		BufferedInputStream stream = new BufferedInputStream(new FileInputStream(data));

		MessageDigest var3;
		try {
			var3 = updateDigest(digest, (InputStream) stream);
		} finally {
			stream.close();
		}

		return var3;
	}

	public static MessageDigest updateDigest(MessageDigest digest, InputStream data) throws IOException {
		byte[] buffer = new byte[1024];

		for (int read = data.read(buffer, 0, 1024); read > -1; read = data.read(buffer, 0, 1024)) {
			digest.update(buffer, 0, read);
		}

		return digest;
	}

	public static MessageDigest updateDigest(MessageDigest messageDigest, String valueToDigest) {
		messageDigest.update(StringUtils.getBytesUtf8(valueToDigest));
		return messageDigest;
	}

	public static boolean isAvailable(String messageDigestAlgorithm) {
		return getDigest(messageDigestAlgorithm, (MessageDigest) null) != null;
	}

	/** @deprecated */
	@Deprecated
	public Digestutils() {
		this.messageDigest = null;
	}

	public Digestutils(MessageDigest digest) {
		this.messageDigest = digest;
	}

	public Digestutils(String name) {
		this(getDigest(name));
	}

	public MessageDigest getMessageDigest() {
		return this.messageDigest;
	}

	public byte[] digest(byte[] data) {
		return updateDigest(this.messageDigest, data).digest();
	}

	public byte[] digest(String data) {
		return updateDigest(this.messageDigest, data).digest();
	}

	public byte[] digest(ByteBuffer data) {
		return updateDigest(this.messageDigest, data).digest();
	}

	public byte[] digest(File data) throws IOException {
		return updateDigest(this.messageDigest, data).digest();
	}

	public byte[] digest(InputStream data) throws IOException {
		return updateDigest(this.messageDigest, data).digest();
	}

	public String digestAsHex(byte[] data) {
		return Hex.encodeHexString(this.digest(data));
	}

	public String digestAsHex(String data) {
		return Hex.encodeHexString(this.digest(data));
	}

	public String digestAsHex(ByteBuffer data) {
		return Hex.encodeHexString(this.digest(data));
	}

	public String digestAsHex(File data) throws IOException {
		return Hex.encodeHexString(this.digest(data));
	}

	public String digestAsHex(InputStream data) throws IOException {
		return Hex.encodeHexString(this.digest(data));
	}
}

方法generateSign中Object data为实体类

import java.util.List;

public class School {

	public String id;
	
	public String address;
	
	public List<Section> sectionList;

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public String getAddress() {
		return address;
	}

	public void setAddress(String address) {
		this.address = address;
	}

	public List<Section> getSectionList() {
		return sectionList;
	}

	public void setSectionList(List<Section> sectionList) {
		this.sectionList = sectionList;
	}
	
	
}
public class Section {

	public String id;
	
	public String name;
	
	public int rs;

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getRs() {
		return rs;
	}

	public void setRs(int rs) {
		this.rs = rs;
	}
	
	
}

### 回答1: 微信支付接口签名是为了保证接口调用的安全性和完整性而生成的一串密文。下面是使用.Net生成微信支付接口签名的步骤: 1. 首先,需要准备以下参数:APPID(公众号或移动应用的唯一标识)、API密钥(微信商户平台设置的密钥)、随机字符串(用于防止重放攻击)、时间戳(接口调用的时间戳,10位的秒级时间戳即可)等。 2. 将上述参数按照字母顺序排序,并拼接成形如“key=value”的字符串,例如:"appid=xxx&mch_id=xxx&nonce_str=xxx&timestamp=xxx"。 3. 在拼接的字符串末尾加上"&key=商户的API密钥"。 4. 使用Hash算法对拼接的字符串进行签名,常用的Hash算法有MD5和SHA1。使用.Net生成签名的代码示例如下: ```csharp using System.Security.Cryptography; using System.Text; string signStr = "拼接的字符串" + "&key=商户的API密钥"; MD5 md5 = MD5.Create(); byte[] signBytes = md5.ComputeHash(Encoding.UTF8.GetBytes(signStr)); StringBuilder sb = new StringBuilder(); foreach (byte b in signBytes) { sb.AppendFormat("{0:x2}", b); } string sign = sb.ToString().ToUpper(); ``` 5. 最后得到的sign就是生成的微信支付接口签名,可以将其加入到支付接口的请求参数中进行发送。 需要注意的是,每次请求的随机字符串和时间戳应该是不同的,以确保签名的唯一性和安全性。生成签名的代码可以根据具体的.Net版本进行调整,上述示例仅为参考。 ### 回答2: 微信支付接口签名是通过对发送的数据进行加密生成的一个字符串,用于校验数据的完整性和真实性。下面是一个基本的生成微信支付接口签名的流程: 1. 首先,将所有发送给微信支付接口参数按照字母序排序,除了sign参数本身,将所有参数参数名和参数值用key=value的形式拼接成一个字符串。 2. 在拼接的字符串末尾加上商户的支付密钥,并将密钥和字符串进行MD5加密,生成一个32位的字符串。这里需要注意,商户支付密钥是在微信商户平台进行配置的,需要在生成签名时正确配置使用。 3. 将生成的签名字符串赋值给sign参数,并将所有参数(包括sign参数)一起发送到微信支付接口。 4. 在接收到微信支付接口的响应时,需要对返回的数据进行校验。将返回的所有参数按照参数名的字母序排序,并按照key=value的形式拼接成一个字符串。 5. 同样地,在拼接的字符串末尾加上商户的支付密钥,进行MD5加密,生成一个32位的字符串。 6. 将生成的签名字符串与返回的sign参数进行比较,如果一致,则表示数据完整和真实;如果不一致,则表示数据可能被篡改了。 通过上述的流程,可以保证微信支付接口的安全和可靠性。需要注意的是,每个接口签名算法可能会有所不同,具体的签名规则和参数配置可以参考微信支付开发文档。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值