md5(信息摘要算法5)用于确保信息传输的完整一致,是计算机广泛的使用杂凑算法之一(又名摘要算法,哈希算法),主流的编程语言普遍已经有md5的实现,将数据(如字符串)运算为另外一个固定长度值,是杂凑算法的基础原理,md5的前生,md5的前身有md2,md4。
1:压缩性:任意长度的数据,算出的md5值长度都是固定的 2:容易计算:从原数据计算出md5值很容易 3:抗修改性:对原数据进行任何的修改,哪怕只修改1个字节,所得到md5值都是固定的 4:强抗碰撞:已知原数据和其md5值,想找到一个具有相同md5值得数据(即伪造数据)是非常困难的
1:MD(Message Digest)
2:SHA(Secure Hash Algorithm)
3:MAC(Message Authentication Code)
java.security.MessageDigest 类主要为应用提供信息摘要算法,也就是用于生成散列码,信息摘要是安全的单项哈希函数,输出固定长度的哈希值,至于具体算法我们暂时不深入!
java 提供三种实现方式:
1:JDK 2:Commons Codec 3:Bouncy Castle
jdk相信大家都有
commons Codec 是Apache家族中提供的编码解码实现,比如Base64,Hex,Md5,Phonetic and URLS等等,下载地址 最新版本1.1
将commons codec jar加入到lib中
第三种方式是bouncy castle java平台的开放轻量级加密解密包 下载地址 引入到项目中
md5 jdk方式 加密实例与验证:
package com.example.encryption;
import com.sun.org.apache.xerces.internal.impl.dv.util.HexBin;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
/**
* @author xuanyouwu
* @email [email protected]
*/
public class Md5Test {
private static String SrcData = "xuanyouwu";
public static void log(String s) {
System.out.println("------>" + s);
}
public static void main(String[] args) throws Exception {
String encyData=md5(SrcData);
log("encyData:"+encyData);
}
private static String md5(String src) {
try {
MessageDigest md5 = MessageDigest.getInstance("MD5");
byte[] digest = md5.digest(src.getBytes());
return HexBin.encode(digest);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return "";
}
}
jdk md5 md2以及sun md4对比
package com.example.encryption;
import com.sun.org.apache.xerces.internal.impl.dv.util.HexBin;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import sun.security.provider.MD4;
/**
* @author xuanyouwu
* @email [email protected]
*/
public class Md5Test {
private static String SrcData = "xuanyouwu";
public static void log(String s) {
System.out.println("------>" + s);
}
public static void main(String[] args) throws Exception {
log("encyData md5:" + md5(SrcData));
log("encyData md2:" + md2(SrcData));
log("encyData md4:" + md4(SrcData));
}
private static String md5(String src) {
try {
MessageDigest md5 = MessageDigest.getInstance("MD5");
byte[] digest = md5.digest(src.getBytes());
return HexBin.encode(digest);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return "";
}
private static String md2(String src) {
try {
MessageDigest md2 = MessageDigest.getInstance("MD2");
byte[] digest = md2.digest(src.getBytes());
return HexBin.encode(digest);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return "";
}
/**
* md4 jdk 本身不提供,这里使用sun
* @param src
* @return
*/
private static String md4(String src) {
try {
MessageDigest md4 = MD4.getInstance();
byte[] digest = md4.digest(src.getBytes());
return HexBin.encode(digest);
} catch (Exception e) {
e.printStackTrace();
}
return "";
}
}
运行结果:
------>encyData md5:3EA5C9303C2BE83F82FFB769345BB338
------>encyData md2:2CC409A3C62177AE523AD5E410A718F4
------>encyData md4:41DDB0C4DE7DE1E4D442F9E110A51F6C
commons_codec 对于md5有两种实现 md5 md2 在org.apache.commons.codec.digest.DigestUtils 类中有提供API:
package com.example.encryption;
import com.sun.org.apache.xerces.internal.impl.dv.util.HexBin;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.codec.digest.DigestUtils;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import sun.security.provider.MD4;
/**
* @author xuanyouwu
* @email [email protected]
*/
public class Md5Test {
private static String SrcData = "xuanyouwu";
public static void log(String s) {
System.out.println("------>" + s);
}
public static void main(String[] args) throws Exception {
log("encyData cc md2:" + ccMd2(SrcData));
log("encyData cc md5:" + ccMd5(SrcData));
}
public static String ccMd5(String src) {
return Hex.encodeHexString(DigestUtils.getMd5Digest().digest(src.getBytes()));
}
public static String ccMd2(String src) {
return Hex.encodeHexString(DigestUtils.getMd2Digest().digest(src.getBytes()));
}
}
bouncy castle 对md加密有三种实现,分别是md5 md4以及md2:
package com.example.encryption;
import com.sun.org.apache.xerces.internal.impl.dv.util.HexBin;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.codec.digest.DigestUtils;
import org.bouncycastle.crypto.digests.MD2Digest;
import org.bouncycastle.crypto.digests.MD4Digest;
import org.bouncycastle.crypto.digests.MD5Digest;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import sun.security.provider.MD4;
/**
* @author xuanyouwu
* @email [email protected]
*/
public class Md5Test {
private static String SrcData = "xuanyouwu";
public static void log(String s) {
System.out.println("------>" + s);
}
public static void main(String[] args) throws Exception {
log("encyData bc md2:" + bcMd2(SrcData));
log("encyData bc md4:" + bcMd4(SrcData));
log("encyData bc md5:" + bcMd5(SrcData));
}
//bouncy castle实现md2方式
public static String bcMd2(String src) {
MD2Digest md2Digest = new MD2Digest();
md2Digest.update(src.getBytes(), 0, src.getBytes().length);
byte[] md2bytes = new byte[md2Digest.getDigestSize()];
md2Digest.doFinal(md2bytes, 0);
return org.bouncycastle.util.encoders.Hex.toHexString(md2bytes);
}
//bouncy castle实现md4方式
public static String bcMd4(String src) {
MD4Digest md4Digest = new MD4Digest();
md4Digest.update(src.getBytes(), 0, src.getBytes().length);
byte[] md4bytes = new byte[md4Digest.getDigestSize()];
md4Digest.doFinal(md4bytes, 0);
return org.bouncycastle.util.encoders.Hex.toHexString(md4bytes);
}
//bouncy castle实现md5方式
public static String bcMd5(String src) {
MD5Digest md5Digest = new MD5Digest();
md5Digest.update(src.getBytes(), 0, src.getBytes().length);
byte[] md5bytes = new byte[md5Digest.getDigestSize()];
md5Digest.doFinal(md5bytes, 0);
return org.bouncycastle.util.encoders.Hex.toHexString(md5bytes);
}
}
运行结果:
------>encyData bc md2:2cc409a3c62177ae523ad5e410a718f4
------>encyData bc md4:41ddb0c4de7de1e4d442f9e110a51f6c
------>encyData bc md5:3ea5c9303c2be83f82ffb769345bb338
另外做android的同学如果引入了databinding框架,google在其中已经盗版了apache commoms codec 的加密解密,无需额外添加jar了