摘要算法是 一种能产生特殊输出格式的算法,这种算法的特色是:不管用户输入什么长度的原始数据,通过计算后输出的密文都是固定长度的,这种算法的原理是根据必定的运算规则对原数据进行某种形式的提取,这种提取就是摘要,被摘要的数据内容与原数据有密切联系,只要原数据稍有改变,输出的“摘要”便彻底不一样,所以,基于这种原理的算法便能对数据完整性提供较为健全的保障。可是,因为输出的密文是提取原数据通过处理的定长值,因此它已经不能还原为原数据,即消息摘要算法是不可逆的,理论上没法经过反向运算取得原数据内容,所以它一般只能被用来作数据完整性验证。java
现在经常使用的“消息摘要”算法经历了多年验证发展而保留下来的算法已经很少,这其中包括MD二、MD四、MD五、SHA、SHA-1/256/383/512等。git
经常使用的摘要算法主要有MD5和SHA1。MD5的输出结果为16字节,sha1的输出结果为20字节。算法
固定长度安全
只要元数据改变,输出摘要彻底不一样函数
只有摘要提取,没有所谓的解码,即不可逆this
java.security.MessageDigest类用于为应用程序提供信息摘要算法的功能,如 MD5 或 SHA 算法。简单点说就是用于生成散列码。信息摘要是安全的单向哈希函数,它接收任意大小的数据,输出固定长度的哈希值。spa
MessageDigest 经过其getInstance系列静态函数来进行实例化和初始化。MessageDigest 对象经过使用 update
方法处理数据。任什么时候候均可以调用 reset
方法重置摘要。一旦全部须要更新的数据都已经被更新了,应该调用 digest
方法之一完成哈希计算并返回结果。设计
将一个字符串进行摘要,而后输出16进制字符串code
public class MD5Util { public final static String MD5(String s) { char hexDigits[]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}; try { byte[] btInput = s.getBytes(); // 得到MD5摘要算法的 MessageDigest 对象 MessageDigest mdInst = MessageDigest.getInstance("MD5"); // 使用指定的字节更新摘要 mdInst.update(btInput); // 得到密文 byte[] md = mdInst.digest(); // 把密文转换成十六进制的字符串形式 int j = md.length; char str[] = new char[j * 2]; int k = 0; for (int i = 0; i < j; i++) { byte byte0 = md[i]; str[k++] = hexDigits[byte0 >>> 4 & 0xf]; str[k++] = hexDigits[byte0 & 0xf]; } return new String(str); } catch (Exception e) { e.printStackTrace(); return null; } } public static void main(String[] args) { System.out.println(MD5Util.MD5("20121221")); System.out.println(MD5Util.MD5("Digest Str......")); } }
SHA-1算法:对象
1995年,发布了SHA-1算法,一般咱们把SHA-1算法简称为SHA算法。SHA-1算法在许多安全协定中广 为使用,包括TLS/SSL、 PGP、SSH、S/MIME和IPsec,曾被视为是MD5算法的后继者。SHA-0和SHA-1算法可对最大长度为264的字节信息作摘要处理,获得 一个160的摘要信息,其设计原理类似于MD4和MD5算法。若是将获得160位的摘要信息换算成十六进制,能够获得一个40位的字符串。
同样的代码结构,调用Digest方法的时候把参数改成"SHA",所以根据上述代码作了如下修改,输出依然是16进制字符串
import java.security.MessageDigest; public class DigestUtil { private enum DigestType{ MD5("MD5") ,SHA("SHA"); private String digestDesc; private DigestType(String digestDesc){ this.digestDesc = digestDesc; } public String getDigestDesc() { return digestDesc; } } private final static String digest(String sourceStr,DigestType type) { char hexDigits[]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}; try { byte[] btInput = sourceStr.getBytes(); // 得到MD5摘要算法的 MessageDigest 对象 MessageDigest mdInst = MessageDigest.getInstance(type.digestDesc); // 使用指定的字节更新摘要 mdInst.update(btInput); // 得到密文 byte[] md = mdInst.digest(); // 把密文转换成十六进制的字符串形式 int j = md.length; char str[] = new char[j * 2]; int k = 0; for (int i = 0; i < j; i++) { byte byte0 = md[i]; str[k++] = hexDigits[byte0 >>> 4 & 0xf]; str[k++] = hexDigits[byte0 & 0xf]; } return new String(str); } catch (Exception e) { e.printStackTrace(); return null; } } public final static String MD5(String s) { return digest(s, DigestType.MD5); } public final static String SHA(String s) { return digest(s, DigestType.SHA); } public static void main(String[] args) { String sourceStr1 = "20121221"; String sourceStr2 = "Digest Str......"; System.out.println(DigestUtil.MD5(sourceStr1)); System.out.println(DigestUtil.MD5(sourceStr2)); System.out.println(DigestUtil.SHA(sourceStr1)); System.out.println(DigestUtil.SHA(sourceStr2)); } }
SHA-2算法:
SHA算法家族除了其表明SHA-1算法之外,还有SHA-22四、SHA-25六、SHA-384和SHA-512四种SHA算法的变体,以其摘 要信息字节长度不一样而命名,一般将这组算法并称为SHA-2算法。摘要信息字节长度的差别是SHA-2和SHA-1算法的最大差别。
继续修改代码
import java.security.MessageDigest; public class DigestUtil { private enum DigestType{ MD5("MD5") ,SHA("SHA") ,SHA256("SHA-256") ,SHA512("SHA-512"); private String digestDesc; private DigestType(String digestDesc){ this.digestDesc = digestDesc; } public String getDigestDesc() { return digestDesc; } } private final static String digest(String sourceStr,DigestType type) { char hexDigits[]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}; try { byte[] btInput = sourceStr.getBytes(); // 得到MD5摘要算法的 MessageDigest 对象 MessageDigest mdInst = MessageDigest.getInstance(type.digestDesc); // 使用指定的字节更新摘要 mdInst.update(btInput); // 得到密文 byte[] md = mdInst.digest(); // 把密文转换成十六进制的字符串形式 int j = md.length; char str[] = new char[j * 2]; int k = 0; for (int i = 0; i < j; i++) { byte byte0 = md[i]; str[k++] = hexDigits[byte0 >>> 4 & 0xf]; str[k++] = hexDigits[byte0 & 0xf]; } return new String(str); } catch (Exception e) { e.printStackTrace(); return null; } } public final static String MD5(String s) { return digest(s, DigestType.MD5); } public final static String SHA(String s) { return digest(s, DigestType.SHA); } public final static String SHA256(String s){ return digest(s, DigestType.SHA256); } public final static String SHA512(String s){ return digest(s, DigestType.SHA512); } public static void main(String[] args) { String sourceStr1 = "20121221"; String sourceStr2 = "Digest Str......"; // System.out.println(DigestUtil.MD5(sourceStr1)); // System.out.println(DigestUtil.MD5(sourceStr2)); // // System.out.println(DigestUtil.SHA(sourceStr1)); // System.out.println(DigestUtil.SHA(sourceStr2)); System.out.println(DigestUtil.SHA256(sourceStr1)); System.out.println(DigestUtil.SHA256(sourceStr2)); System.out.println(DigestUtil.SHA512(sourceStr1)); System.out.println(DigestUtil.SHA512(sourceStr2)); } }