MD是一种单向加密算法,是不可逆的一种的加密方式。(就是把一个任意长度的字节串变换成一定长的十六进制数字串),除了MD5以外,其中比较有名的还有sha-1、RIPEMD以及Haval等算法。
特点
1、压缩性:任意长度的数据,算出的MD5值长度都是固定的。
2、容易计算:从原数据计算出MD5值很容易。
3、抗修改性:对原数据进行任何改动,哪怕只修改1个字节,所得到的MD5值都有很大区别。
4、强抗碰撞:已知原数据和其MD5值,想找到一个具有相同MD5值的数据(即伪造数据)是非常困难的。
应用场景
1、一致性验证 (确认数据未被修改)
2、数字签名 (生成一个特定的字符串,确保唯一性)
3、安全访问认证 (登陆密码MD5加密后更服务器现有的密码MD5码对比)
代码实现
1)计算字符串MD5值
public static String md5(String string) {
if (TextUtils.isEmpty(string)) {
return "";
}
try {
MessageDigest md5Digest = MessageDigest.getInstance("MD5");
byte[] digest = md5Digest.digest(string.getBytes());
StringBuilder sb = new StringBuilder();
for (byte b : digest) {
int temp = b & 0xff;//加盐
String hexString = Integer.toHexString(temp);
if (hexString.length() == 1) {//如果遇到数字长度为1,如:7->07 9->09 ...
sb.append("0");
}
sb.append(hexString);
}
return sb.toString();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return null;
}
2)计算文件的MD5值(方式一)
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;
}
3)计算文件的MD5值(方式二 Java NIO)
/**
* Java NIO(New IO)是从Java 1.4版本开始引入的一个新的IO API,可以替代标准的Java IO API。
* 计算文件的 MD5 值,采用nio的方式
*/
public static String md5(File file, String method) {
if (!method.equals("nio")) {
return "";
}
String result = "";
FileInputStream in = null;
try {
in = new FileInputStream(file);
MappedByteBuffer byteBuffer = in.getChannel().map(FileChannel.MapMode.READ_ONLY, 0, file.length());
MessageDigest md5 = MessageDigest.getInstance("MD5");
md5.update(byteBuffer);
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加密安全性探讨
1)对字符串多次MD5加密
/**
* MD5加密安全性之对字符串多次加密
*/
public static String md5(String string, int times) {
if (TextUtils.isEmpty(string)) {
return "";
}
String md5 = md5(string);
for (int i = 0; i < times - 1; i++) {
md5 = md5(md5);
}
return md5(md5);
}
2.)MD5加盐(加盐的方式也是多种多样)
1、string+key(盐值key)然后进行MD5加密;
2、用string明文的hashcode作为盐,然后进行MD5加密;
3、随机生成一串字符串作为盐,然后进行MD5加密
/**
* MD5加密安全性之string+key(盐值key)然后进行MD5加密
* @param string
* @param slat 手动加盐值
* @return
*/
public static String md5(String string, String slat) {
if (TextUtils.isEmpty(string)) {
return "";
}
MessageDigest md5 = null;
try {
md5 = MessageDigest.getInstance("MD5");
byte[] bytes = md5.digest((string + slat).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 "";
}
追及
完整代码参考github:Android-Encrypt-master