一.MD5简介
MD5英文全称“Message-Digest Algorithm 5”,翻译过来是“消息摘要算法5”,由MD2、MD3、MD4演变过来的,是一种单向加密算法,是不可逆的一种的加密方式。
二.算法原理
对MD5算法简要的叙述可以为:MD5以512位分组来处理输入的信息,且每一分组又被划分为16个32位子分组,经过了一系列的处理后,算法的输出由四个32位分组组成,将这四个32位分组级联后将生成一个128位散列值。
总体流程如下图所示, 表示第i个分组,每次的运算都由前一轮的128位结果值和第i块512bit值进行运算。
三.MD5加密特点
压缩性:任意长度的数据,算出的MD5值长度都是固定的。
容易计算:从原数据计算出MD5值很容易。
抗修改性:对原数据进行任何改动,哪怕只修改1个字节,所得到的MD5值都有很大区别。
强抗碰撞:已知原数据和其MD5值,想找到一个具有相同MD5值的数据(即伪造数据)是非常困难的。
四.MD5应用场景
一致性验证
数字签名
安全访问认证
五.代码说明
工具类
package com.wjn.okhttpmvpdemo.mode.utils;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
/*
* MD5 算法
*/
public class MD5 {
//全局数组
private final static String[] strDigits = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"};
/**
* MD5加密
*/
public static String GetMD5Code(String strObj) {
String resultString = null;
try {
resultString = new String(strObj);
MessageDigest md = MessageDigest.getInstance("MD5");
// md.digest() 该函数返回值为存放哈希值结果的byte数组
resultString = byteToString(md.digest(strObj.getBytes()));
} catch (NoSuchAlgorithmException ex) {
ex.printStackTrace();
}
return resultString;
}
/**
* 转换字节数组为16进制字串
*/
private static String byteToString(byte[] bByte) {
StringBuffer sBuffer = new StringBuffer();
for (int i = 0; i < bByte.length; i++) {
sBuffer.append(byteToArrayString(bByte[i]));
}
return sBuffer.toString();
}
/**
* 返回形式为数字+字符串
*/
private static String byteToArrayString(byte bByte) {
int iRet = bByte;
if (iRet < 0) {
iRet += 256;
}
int iD1 = iRet / 16;
int iD2 = iRet % 16;
return strDigits[iD1] + strDigits[iD2];
}
}
调用
/**
* MD5加密
* */
private void myMD5Method(){
String str1="password123456";
String md51= MD5.GetMD5Code(str1);
Log.d("TAG",str1+" 加密后----:"+md51);
Log.d("TAG","长度----:"+md51.length());
String str2="password";
String md52= MD5.GetMD5Code(str2);
Log.d("TAG",str2+" 加密后----:"+md52);
Log.d("TAG","长度----:"+md52.length());
String str3="今天是你的生日,我的中国236598";
String md53= MD5.GetMD5Code(str3);
Log.d("TAG",str3+" 加密后----:"+md53);
Log.d("TAG","长度----:"+md53.length());
}
结果
由上可见 任意长度的数据,算出的MD5值长度都是固定的32位。
工具类 (字符串MD5加密其他写法)
package com.wjn.okhttpmvpdemo.mode.utils;
import android.text.TextUtils;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
/*
* MD5 算法
*/
public class MD5s {
public static String md5(String string) {
if (TextUtils.isEmpty(string)) {
return "";
}
MessageDigest md5 = null;
try {
md5 = MessageDigest.getInstance("MD5");
byte[] bytes = md5.digest(string.getBytes());
String result = "";
for (byte b : bytes) {
String temp = Integer.toHexString(b & 0xff);
if (temp.length() == 1) {
temp = "0" + temp;
}
result += temp;
}
return result;
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return "";
}
}
调用
/**
* MD5加密
* */
private void myMD5Method(){
String str3="今天是你的生日,我的中国236598";
String md53= MD5.GetMD5Code(str3);
String md533= MD5s.md5(str3);
boolean b=md53.equals(md533);
String result=(b? "相等":"不相等");
Log.d("TAG",str3+" 加密后111----:"+md53);
Log.d("TAG",str3+" 加密后222----:"+md533);
Log.d("TAG",md53+" 和 "+md533+" 是否相等:"+result);
}
结果
工具类 (文件加密)
package com.wjn.okhttpmvpdemo.mode.utils;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.MessageDigest;
/*
* MD5 算法
*/
public class MD5ss {
public static String md5(File file) {
if (file == null || !file.isFile() || !file.exists()) {
return "";
}
FileInputStream in = null;
String result = "";
byte buffer[] = new byte[8192];
int len;
try {
MessageDigest md5 = MessageDigest.getInstance("MD5");
in = new FileInputStream(file);
while ((len = in.read(buffer)) != -1) {
md5.update(buffer, 0, len);
}
byte[] bytes = md5.digest();
for (byte b : bytes) {
String temp = Integer.toHexString(b & 0xff);
if (temp.length() == 1) {
temp = "0" + temp;
}
result += temp;
}
} catch (Exception e) {
e.printStackTrace();
}finally {
if(null!=in){
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return result;
}
}
调用
/**
* MD5加密
* */
private void myMD5Method(){
File file=new File("/storage/emulated/0/base64test.txt");
String result= MD5ss.md5(file);
File files=new File("/storage/emulated/0/base64test_new.txt");
String results= MD5ss.md5(files);
boolean b=result.equals(results);
String string=(b? "相等":"不相等");
Log.d("TAG","base64test.txt MD5文件加密后:"+result);
Log.d("TAG","base64test.txt MD5文件加密后字符串长度:"+result.length());
Log.d("TAG","base64test_new.txt MD5文件加密后:"+results);
Log.d("TAG","base64test_new.txt MD5文件加密后字符串长度:"+results.length());
Log.d("TAG","base64test.txt 和 base64test_new.txt MD5文件加密后字符串是否相等:"+" "+string);
}
结果
说明:上述代码 base64test.txt文件 与 base64test_new.txt文件只是文件名不同 内容完全一致 MD5加密后的字符串也是一致的。