Java安全密碼學-(五)消息摘要

消息摘要

消息摘要(Message Digest)又稱爲數字摘要(Digital Digest)

它是一個唯一對應一個消息或文本的固定長度的值,它由一個單向Hash加密函數對消息進行作用而產生

使用數字摘要生成的值是不可以篡改的,爲了保證文件或者值的安全

 

特點

無論輸入的消息有多長,計算出來的消息摘要的長度總是固定的。例如應用MD5算法摘要的消息有128個比特位,用SHA-1算法摘要的消息最終有160比特位的輸出

只要輸入的消息不同,對其進行摘要以後產生的摘要消息也必不相同;但相同的輸入必會產生相同的輸出

消息摘要是單向、不可逆的

 

常見算法

- MD5
- SHA1
- SHA256
- SHA512

 

獲取字符串消息摘要

package com.atguigu.digest;

import javax.sound.midi.Soundbank;
import java.security.MessageDigest;

/**
 * DigestDemo1
 *
 * @Author: 尚硅谷
 * @CreateTime: 2020-03-17
 * @Description:
 */
public class DigestDemo1 {

    public static void main(String[] args) throws Exception{
        // 原文
        String input = "aa";
        // 算法
        String algorithm = "MD5";
        // 獲取數字摘要對象
        MessageDigest messageDigest = MessageDigest.getInstance(algorithm);
        // 獲取消息數字摘要的字節數組
        byte[] digest = messageDigest.digest(input.getBytes());
         // base64編碼
        System.out.println(Base64.encode(digest));
    }
}

數字摘要轉換成 16 進制

// 4124bc0a9335c27f086f24ba207a4912     md5 在線校驗
// QSS8CpM1wn8IbyS6IHpJEg==             消息摘要使用的是16進制

 

數字摘要算法

package com.atguigu.digest;

import com.sun.org.apache.xml.internal.security.utils.Base64;

import javax.sound.midi.Soundbank;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/**
 * DigestDemo1
 *
 * @Author: 尚硅谷
 * @CreateTime: 2020-03-17
 * @Description:
 */
public class DigestDemo1 {

    public static void main(String[] args) throws Exception{
        // 4124bc0a9335c27f086f24ba207a4912     md5 在線校驗
        // QSS8CpM1wn8IbyS6IHpJEg==             消息摘要使用的是16進制
        // 原文
        String input = "aa";
        // 算法
        String algorithm = "MD5";
        // 獲取數字摘要對象
        String md5 = getDigest(input, "MD5");
        System.out.println(md5);

        String sha1 = getDigest(input, "SHA-1");
        System.out.println(sha1);

        String sha256 = getDigest(input, "SHA-256");
        System.out.println(sha256);

        String sha512 = getDigest(input, "SHA-512");
        System.out.println(sha512);


    }

    private static String toHex(byte[] digest) throws Exception {

//        System.out.println(new String(digest));
        // base64編碼
//        System.out.println(Base64.encode(digest));
        // 創建對象用來拼接
        StringBuilder sb = new StringBuilder();

        for (byte b : digest) {
            // 轉成 16進制
            String s = Integer.toHexString(b & 0xff);
            if (s.length() == 1){
                // 如果生成的字符只有一個,前面補0
                s = "0"+s;
            }
            sb.append(s);
        }
        System.out.println("16進制數據的長度:" + sb.toString().getBytes().length);
        return sb.toString();
    }

    private static String getDigest(String input, String algorithm) throws Exception {
        MessageDigest messageDigest = MessageDigest.getInstance(algorithm);
        // 消息數字摘要
        byte[] digest = messageDigest.digest(input.getBytes());
        System.out.println("密文的字節長度:" + digest.length);

        return toHex(digest);
    }
}

 獲取文件的數字摘要

public class DigestDemo {

    public static void main(String[] args) throws Exception{
        String input = "aa";
        String algorithm = "MD5";

        // sha1 可以實現秒傳功能

        String sha1 = getDigestFile("apache-tomcat-9.0.10-windows-x64.zip", "SHA-1");
        System.out.println(sha1);

        String sha512 = getDigestFile("apache-tomcat-9.0.10-windows-x64.zip", "SHA-512");
        System.out.println(sha512);

        String md5 = getDigest("aa", "MD5");
        System.out.println(md5);

        String md51 = getDigest("aa ", "MD5");
        System.out.println(md51);
    }

    private static String getDigestFile(String filePath, String algorithm) throws Exception{
        FileInputStream fis = new FileInputStream(filePath);
        int len;
        byte[] buffer = new byte[1024];
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        while ( (len =  fis.read(buffer))!=-1){
            baos.write(buffer,0,len);
        }
        // 獲取消息摘要對象
        MessageDigest messageDigest = MessageDigest.getInstance(algorithm);
        // 獲取消息摘要
        byte[] digest = messageDigest.digest(baos.toByteArray());
        System.out.println("密文的字節長度:"+digest.length);
        return toHex(digest);
    }

    private static String getDigest(String input, String algorithm) throws Exception{
        MessageDigest messageDigest = MessageDigest.getInstance(algorithm);
        byte[] digest = messageDigest.digest(input.getBytes());
        System.out.println("密文的字節長度:"+digest.length);
        return toHex(digest);
    }

    private static String toHex(byte[] digest) {
        //        System.out.println(new String(digest));
        // 消息摘要進行表示的時候,是用16進制進行表示
        StringBuilder sb = new StringBuilder();
        for (byte b : digest) {
            // 轉成16進制

            String s = Integer.toHexString(b & 0xff);
            // 保持數據的完整性,前面不夠的用0補齊
            if (s.length()==1){
                s="0"+s;
            }
            sb.append(s);
        }
        System.out.println("16進制數據的長度:"+ sb.toString().getBytes().length);
        return sb.toString();
    }
}

總結

MD5算法 : 摘要結果16個字節, 轉16進制後32個字節

SHA1算法 : 摘要結果20個字節, 轉16進制後40個字節

SHA256算法 : 摘要結果32個字節, 轉16進制後64個字節

SHA512算法 : 摘要結果64個字節, 轉16進制後128個字節

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章