MD5、SHA、SHA-2算法的实现(Java)

概念

摘要算法是 一种能产生特殊输出格式的算法,这种算法的特点是:无论用户输入什么长度的原始数据,经过计算后输出的密文都是固定长度的,这种算法的原理是根据一定的运算规则对原数据进行某种形式的提取,这种提取就是摘要,被摘要的数据内容与原数据有密切联系,只要原数据稍有改变,输出的“摘要”便完全不同,因此,基于这种原理的算法便能对数据完整性提供较为健全的保障。但是,由于输出的密文是提取原数据经过处理的定长值,所以它已经不能还原为原数据,即消息摘要算法是不可逆的,理论上无法通过反向运算取得原数据内容,因此它通常只能被用来做数据完整性验证。

如今常用的“消息摘要”算法经历了多年验证发展而保留下来的算法已经不多,这其中包括MD2、MD4、MD5、SHA、SHA-1/256/383/512等。

常用的摘要算法主要有MD5和SHA1。MD5的输出结果为16字节,sha1的输出结果为20字节。

要点

固定长度

只要元数据改变,输出摘要完全不同

只有摘要提取,没有所谓的解码,即不可逆

常见摘要算法的实现(Java)

java.security.MessageDigest类用于为应用程序提供信息摘要算法的功能,如 MD5 或 SHA 算法。简单点说就是用于生成散列码。信息摘要是安全的单向哈希函数,它接收任意大小的数据,输出固定长度的哈希值。

MessageDigest 通过其getInstance系列静态函数来进行实例化和初始化。MessageDigest 对象通过使用 update 方法处理数据。任何时候都可以调用 reset 方法重置摘要。一旦所有需要更新的数据都已经被更新了,应该调用 digest 方法之一完成哈希计算并返回结果。

MD5

将一个字符串进行摘要,然后输出16进制字符串

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

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-2算法:

SHA算法家族除了其代表SHA-1算法以外,还有SHA-224、SHA-256、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));
         
    }
}

猜你喜欢

转载自my.oschina.net/u/3383536/blog/1624122
今日推荐