前言:
项目中需要调用其他系统的 api 接口,接口使用的是按一定规则生成 MD5 密文作为签名来进行身份验证,本文仅记录 32 位 MD5 密文的生成方式,仅供参考。
什么是MD5 加密?
MD5 加密是一种加密算法,MD5 加密算法被广泛使用的密码散列函数,可以产生出一个128位(16字节)的散列值(hash value),用于确保信息传输完整一致,同时 MD5 加密是一种不可逆的加密算法,不可逆加密算法的特征是加密过程中不需要使用密钥,输入明文后由系统直接经过加密算法处理成密文,这种加密后的数据是无法被解密的,只有重新输入明文,并再次经过同样加密算法处理,得到相同的密文被系统重新识别后,才能真正解密。
对方系统签名规则:
1、构造签名因子:将Headers除"sign"外的所有参数按key进行字!典升序排列。
2、构造签名因子:将第1步中排序后的参数(key=value)用&拼接起来。
2、对构造的签名因子执行md5_32位算法,sign=uppercase (md5_32(s))得到签名。
生成 MD5 签名规则的工具类:
@Slf4j
public class MD5Utils {
/**
* @Description: MD5 加密
* @Date: 2024/4/3 13:38
*/
public static String md5Encrypt(String plainText) {
String cipherText;
try {
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(plainText.getBytes());
byte[] bytes = md.digest();
int i;
StringBuilder buf = new StringBuilder();
for (byte aByte : bytes) {
i = aByte;
if (i < 0) {
i += 256;
}
if (i < 16) {
buf.append("0");
}
buf.append(Integer.toHexString(i));
}
cipherText = buf.toString();
} catch (NoSuchAlgorithmException e) {
log.error("MD5 加密失败,失败原因:", e);
throw new BusinessException("MD5 加密失败");
}
return cipherText;
}
/**
* @Description: 排序并构造参数
* @Date: 2024/4/3 13:57
*/
public static String formatParam(Map<String, String> param) {
String params;
try {
List<Map.Entry<String, String>> itmes = new ArrayList<>(param.entrySet());
//对所有传入的参数按照字段名从小到大排序
//Collections.sort(items); 默认正序
//可通过实现Comparator接口的compare方法来完成自定义排序
itmes.sort(Map.Entry.comparingByKey());
/*Collections.sort(itmes, new Comparator<Map.Entry<String, String>>() {
@Override
public int compare(Map.Entry<String, String> o1, Map.Entry<String, String> o2) {
return (o1.getKey().toString().compareTo(o2.getKey()));
}
});*/
//构造key=value键值对的形式
StringBuilder sb = new StringBuilder();
for (Map.Entry<String, String> item : itmes) {
if (StringUtils.isNotBlank(item.getKey())) {
sb.append(item.getKey()).append("=").append(item.getValue());
sb.append("&");
}
}
params = sb.toString();
if (!params.isEmpty()) {
params = params.substring(0, params.length() - 1);
}
} catch (Exception e) {
log.error("sign 签名构造失败,失败原因:", e);
throw new BusinessException("sign 签名构造失败");
}
return params;
}
}
如有错误的地方欢迎指出纠正。