MD5加密是一种常见的加密方式,我们经常用在保存用户密码和关键信息上。那么它到底有什么,又什么好处呢,会被这么广泛的运用在应用开发中。
1、什么是MD5
MD5加密全程是Message-Digest Algoorithm 5(信息-摘要算法),它对信息进行摘要采集,再通过一定的位运算,最终获取加密后的MD5字符串。
例如我们要加密一篇文章,那么我们会随机从每段话或者每行中获取一个字,把这些字统计出来后,再通过一定的运算获得一个固定长度的MD5加密后信息。因此,其很难被逆向破解。
MD5算法具有以下特点:
1、压缩性:任意长度的数据,算出的MD5值长度都是固定的。
2、容易计算:从原数据计算出MD5值很容易。
3、抗修改性:对原数据进行任何改动,哪怕只修改1个字节,所得到的MD5值都有很大区别。
4、弱抗碰撞:已知原数据和其MD5值,想找到一个具有相同MD5值的数据(即伪造数据)是非常困难的。
5、强抗碰撞:想找到两个不同的数据,使它们具有相同的MD5值,是非常困难的。
MD5的作用是让大容量信息在用数字签名软件签署私人密钥前被”压缩”成一种保密的格式(就是把一个任意长度的字节串变换成一定长的十六进制数字串)。除了MD5以外,其中比较有名的还有sha-1、RIPEMD以及Haval等。
在讲解MD5签名原理之前,必须明白MD5是不可逆的,也就是不可破解的,当然可能稍有了解的人会说MD5可以破解,当然,网上也有一些强大的数据库会把各种数据组合的MD5收集起来形成强大的数据库,能冠军数据库搜索可能一些简单的数据会马上找出某些组合对应的MD5值,但咱说的MD5签名生成是最少32位的数值MD5加密,所以这个破解的可能性是非常非常非常小的。所以这还是比较安全的。
原理很简单,请求方对请求数据按一定的规则排序,加上appkey码一起通过MD5加密生成签名,然后把请求数据和签名发给服务方,服务方拿到数据后,去掉appid和无用的数据,通过appid找到请求方的appkey,然后按同样的规则处理数据,并加上appkey通过MD5加密也生成签名,然后和请求方生成的签名去对比,如果值一样,签名验证通过。
服务商一般会给你一个appid,appkey;同时这两个参数服务商也会保存,这两个形成了你的唯一标识。
appid通过网络传输,而appkey是不在网络上进行传输的,只在生成签名时使用,所以安全性还是比较高的。
1. 除去加密数组中的空值和签名参数
2. 对数组排序
3. 把数组所有元素,按照“参数=参数值”的模式用“&”字符拼接成字符串
4. 加上appkey值,对形成的数据进行MD5加密,生成签名
签名生成的通用步骤如下:
第一步,设所有发送或者接收到的数据为集合M,将集合M内非空参数值的参数按照参数名ASCII码从小到大排序(字典序),使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串stringA。
特别注意以下重要规则:
◆ 参数名ASCII码从小到大排序(字典序);
◆ 如果参数的值为空不参与签名;
◆ 参数名区分大小写;
◆ 验证调用返回或微信主动通知签名时,传送的sign参数不参与签名,将生成的签名与该sign值作校验。
◆ 微信接口可能增加字段,验证签名时必须支持增加的扩展字段
第二步,在stringA最后拼接上key得到stringSignTemp字符串,并对stringSignTemp进行MD5运算,再将得到的字符串所有字符转换为大写,得到sign值signValue。
public static void main(String[] args) {
SortedMap
MD5Utils
package com.ykx.transfer.util;
import java.security.MessageDigest;
/**
* @Author:Starry
* @Description:
* @Date:Created in 9:46 2018/4/13
* Modified By:
*/
public class MD5Utils {
private static final String hexDigIts[] = {"0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"};
/**
* MD5加密
* @param origin 字符
* @param charsetname 编码
* @return
*/
public static String MD5Encode(String origin, String charsetname){
String resultString = null;
try{
resultString = new String(origin);
MessageDigest md = MessageDigest.getInstance("MD5");
if(null == charsetname || "".equals(charsetname)){
resultString = byteArrayToHexString(md.digest(resultString.getBytes()));
}else{
resultString = byteArrayToHexString(md.digest(resultString.getBytes(charsetname)));
}
}catch (Exception e){
}
return resultString;
}
public static String byteArrayToHexString(byte b[]){
StringBuffer resultSb = new StringBuffer();
for(int i = 0; i < b.length; i++){
resultSb.append(byteToHexString(b[i]));
}
return resultSb.toString();
}
public static String byteToHexString(byte b){
int n = b;
if(n < 0){
n += 256;
}
int d1 = n / 16;
int d2 = n % 16;
return hexDigIts[d1] + hexDigIts[d2];
}
}
原文:https://blog.csdn.net/chenghaibing2008/article/details/79701773
https://www.jianshu.com/p/e765a6f9db58
https://blog.csdn.net/qq_30683329/article/details/80879058