欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java實(shí)現(xiàn)MD5加密的四種方式

 更新時(shí)間:2025年03月18日 11:14:57   作者:思靜魚(yú)  
MD5是一種廣泛使用的哈希算法,其輸出結(jié)果是一個(gè)128位的二進(jìn)制數(shù),通常以32位十六進(jìn)制數(shù)的形式表示,MD5 的底層實(shí)現(xiàn)涉及多個(gè)復(fù)雜的步驟和算法,本文給大家介紹了Java實(shí)現(xiàn)MD5加密的四種方式,需要的朋友可以參考下

MD5介紹

MD5(Message-Digest Algorithm 5)是一種廣泛使用的哈希算法,其輸出結(jié)果是一個(gè)128位的二進(jìn)制數(shù),通常以32位十六進(jìn)制數(shù)的形式表示。因此,MD5的輸出結(jié)果可以表示為一個(gè)32位的字符串。

MD5算法常用于數(shù)據(jù)完整性驗(yàn)證、密碼加密等場(chǎng)景,通常將輸入的數(shù)據(jù)經(jīng)過(guò)MD5處理后,得到一個(gè)32位的摘要(digest),該摘要作為數(shù)據(jù)的唯一表示,可以用于驗(yàn)證數(shù)據(jù)的完整性或作為密碼的加密存儲(chǔ)。需要注意的是,由于MD5算法本身存在安全性問(wèn)題,已經(jīng)不再推薦用于密碼加密等安全場(chǎng)景,而應(yīng)該使用更加安全的算法,如SHA-2、bcrypt等。

MD5(Message Digest Algorithm 5)是一種哈希函數(shù),而不是對(duì)稱加密算法。MD5 用于產(chǎn)生一個(gè)稱為消息摘要(Message Digest)的固定大小的哈希值,通常是 128 位。MD5 不是加密算法,因?yàn)楣V凳遣豢赡娴?,即無(wú)法從哈希值還原出原始數(shù)據(jù)。

對(duì)稱加密算法是一種使用相同密鑰進(jìn)行加密和解密的算法,例如 DES(Data Encryption Standard)、AES(Advanced Encryption Standard)等。與對(duì)稱加密不同,哈希函數(shù)通常是單向的,只能從原始數(shù)據(jù)計(jì)算出哈希值,而無(wú)法從哈希值還原出原始數(shù)據(jù)。

安全性:MD5 已經(jīng)被認(rèn)為不再安全,因?yàn)樗菀资艿脚鲎补?。?duì)于需要安全性的應(yīng)用(如密碼存儲(chǔ)),建議使用更強(qiáng)的散列算法(如 SHA-256)和適當(dāng)?shù)陌踩珜?shí)踐(如加鹽)。

性能:雖然 MD5 在性能上表現(xiàn)良好,但現(xiàn)代安全需求通常需要更強(qiáng)的散列算法。

MD5(Message Digest Algorithm 5)是一種廣泛使用的加密散列函數(shù),主要用于生成數(shù)據(jù)的唯一摘要值(哈希值)。MD5 的底層實(shí)現(xiàn)涉及多個(gè)復(fù)雜的步驟和算法。以下是 MD5 的底層工作原理和關(guān)鍵概念:

  1. 基本概念
    散列函數(shù):MD5 是一種散列函數(shù),用于將任意長(zhǎng)度的輸入數(shù)據(jù)(消息)映射為固定長(zhǎng)度的輸出(128 位,或 16 字節(jié))的哈希值。
    不可逆性:MD5 生成的哈希值理論上無(wú)法逆推出原始輸入數(shù)據(jù)。
    固定長(zhǎng)度:無(wú)論輸入數(shù)據(jù)的長(zhǎng)度如何,MD5 總是生成一個(gè) 128 位的哈希值。
  2. MD5 的步驟
    MD5 的底層算法包括以下主要步驟:
  3. 初始化
    MD5 使用四個(gè) 32 位的初始常量(A、B、C、D)作為計(jì)算的起始值:
    ( A = 0x67452301 )
    ( B = 0xEFCDAB89 )
    ( C = 0x98BADCFE )
    ( D = 0x10325476 )
    這些常量用于初始化 MD5 的內(nèi)部狀態(tài)。
  4. 填充
    將輸入數(shù)據(jù)填充到 512 位的倍數(shù)。填充過(guò)程包括:
    填充位:在輸入數(shù)據(jù)的末尾添加一個(gè) 1 位的標(biāo)志位,表示數(shù)據(jù)結(jié)束。
    填充零:在標(biāo)志位后添加零,直到數(shù)據(jù)長(zhǎng)度接近 512 位。
    附加長(zhǎng)度:在數(shù)據(jù)末尾附加原始數(shù)據(jù)的長(zhǎng)度(以位為單位),以 64 位表示。填充后的數(shù)據(jù)總長(zhǎng)度為 512 位的倍數(shù)。
  5. 數(shù)據(jù)分塊
    將填充后的數(shù)據(jù)分成 512 位的塊,每個(gè)塊被進(jìn)一步分成 16 個(gè) 32 位的子塊(總共 64 個(gè)字節(jié))。
  6. 處理每個(gè)數(shù)據(jù)塊
    對(duì)于每個(gè) 512 位的數(shù)據(jù)塊,執(zhí)行以下步驟:
    擴(kuò)展:將 16 個(gè) 32 位子塊擴(kuò)展為 64 個(gè) 32 位的子塊,使用非線性函數(shù)進(jìn)行處理。
    輪次:MD5 使用 64 輪的運(yùn)算,每一輪使用不同的非線性函數(shù)(F、G、H、I)和常量(T[i])。每輪的運(yùn)算包括:
    非線性函數(shù):F(x, y, z)、G(x, y, z)、H(x, y, z)、I(x, y, z)
    常量:T[i] 是一組預(yù)定義的常量,與輸入數(shù)據(jù)和輪次相關(guān)。
    位運(yùn)算:使用位移和按位與、或、異或等運(yùn)算來(lái)更新內(nèi)部狀態(tài)(A、B、C、D)。
    數(shù)據(jù)混合:將數(shù)據(jù)塊與當(dāng)前的內(nèi)部狀態(tài)進(jìn)行混合。
  7. 輸出
    將最后一個(gè)數(shù)據(jù)塊的處理結(jié)果(A、B、C、D)連接起來(lái),生成 128 位(16 字節(jié))的哈希值。
  8. MD5 算法的詳細(xì)步驟
    填充:
    在原始消息末尾添加 1 位的 1。
    添加足夠的 0,使得消息長(zhǎng)度(包括填充的部分)為 448 位(512 位的前 448 位),即還需填充 0 到 64 位數(shù)據(jù)塊的長(zhǎng)度。
    添加 64 位的消息長(zhǎng)度,作為填充的最后部分,確保最終消息長(zhǎng)度為 512 位的倍數(shù)。
    初始化變量:
    初始化 A、B、C、D 為常量值。
    處理數(shù)據(jù)塊:
    將每個(gè)數(shù)據(jù)塊分成 16 個(gè) 32 位的子塊,使用特定的非線性函數(shù)和常量進(jìn)行處理。
    進(jìn)行 64 輪的運(yùn)算,更新 A、B、C、D 的值。
    輸出結(jié)果:
    將 A、B、C、D 的最終值轉(zhuǎn)換為 128 位的哈希值,通常以 16 進(jìn)制表示。
  9. MD5 的應(yīng)用
    數(shù)據(jù)完整性檢查:通過(guò)比較文件的 MD5 哈希值,可以檢測(cè)文件是否被篡改。
    密碼存儲(chǔ):在數(shù)據(jù)庫(kù)中存儲(chǔ)密碼的 MD5 哈希值,而不是明文密碼(注意:不建議僅使用 MD5 存儲(chǔ)密碼,因?yàn)樗驯蛔C明不夠安全)。
  10. 安全性
    雖然 MD5 曾被廣泛使用,但由于其安全性問(wèn)題,如碰撞攻擊(即不同的輸入可以產(chǎn)生相同的哈希值),它已不再被認(rèn)為是安全的。對(duì)于需要更高安全性的應(yīng)用,建議使用更強(qiáng)的哈希函數(shù),如 SHA-256 或 SHA-3。
    總結(jié)
    MD5 是一種將輸入數(shù)據(jù)映射到固定長(zhǎng)度哈希值的散列函數(shù)。其底層實(shí)現(xiàn)包括數(shù)據(jù)填充、分塊、處理和最終輸出四個(gè)主要步驟。盡管 MD5 在許多應(yīng)用中曾被廣泛使用,但由于安全性問(wèn)題,現(xiàn)如今建議使用更安全的哈希算法。

Java 中實(shí)現(xiàn) MD5 加密方式

這三種方法都能有效地生成 MD5 哈希。選擇適合你項(xiàng)目需求的方式,如果已經(jīng)使用了 Apache Commons Codec 或 Guava,可以直接利用它們的功能;如果只是簡(jiǎn)單的 MD5 加密需求,使用 MessageDigest 是最直接的方法。
在 Java 中實(shí)現(xiàn) MD5 加密可以通過(guò)多種方式。

方法一:使用 MessageDigest

這是最基本的方式,使用 Java 內(nèi)置的 MessageDigest 類。

示例代碼:

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class MD5UsingMessageDigest {
    public static String md5(String input) {
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] messageDigest = md.digest(input.getBytes());
            StringBuilder hexString = new StringBuilder();
            for (byte b : messageDigest) {
                String hex = Integer.toHexString(0xff & b);
                if (hex.length() == 1) {
                    hexString.append('0');
                }
                hexString.append(hex);
            }
            return hexString.toString();
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        }
    }

    public static void main(String[] args) {
        String input = "Hello, World!";
        System.out.println("MD5 Hash: " + md5(input));
    }
}

方法二:使用 Apache Commons Codec

Apache Commons Codec 是一個(gè)流行的庫(kù),提供了便捷的工具類進(jìn)行編碼和解碼。

示例代碼:

首先,確保在項(xiàng)目中添加 Apache Commons Codec 的依賴:

<dependency>
    <groupId>commons-codec</groupId>

    <artifactId>commons-codec</artifactId>

    <version>1.15</version> <!-- 檢查最新版本 -->
</dependency>

然后可以使用以下代碼:

import org.apache.commons.codec.digest.DigestUtils;

public class MD5UsingCommonsCodec {
    public static void main(String[] args) {
        String input = "Hello, World!";
        String md5Hash = DigestUtils.md5Hex(input);
        System.out.println("MD5 Hash: " + md5Hash);
    }
}

方法三:使用 Guava

Google 的 Guava 庫(kù)也提供了簡(jiǎn)單的 MD5 加密功能。

示例代碼:

首先,確保在項(xiàng)目中添加 Guava 的依賴:

<dependency>
    <groupId>com.google.guava</groupId>

    <artifactId>guava</artifactId>

    <version>31.0.1-jre</version> <!-- 檢查最新版本 -->
</dependency>

然后可以使用以下代碼:

import com.google.common.hash.Hashing;

import java.nio.charset.StandardCharsets;

public class MD5UsingGuava {
    public static void main(String[] args) {
        String input = "Hello, World!";
        String md5Hash = Hashing.md5()
                .hashString(input, StandardCharsets.UTF_8)
                .toString();
        System.out.println("MD5 Hash: " + md5Hash);
    }
}

方法四:SPRING核心包

import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HashController {

    @GetMapping("/md5")
    public String getMD5(@RequestParam String input) {
        return DigestUtils.md5DigestAsHex(input.getBytes());
    }
}

MD5Util

package com.maxvision.common.util;

import lombok.extern.slf4j.Slf4j;

import java.security.MessageDigest;

@Slf4j
public class MD5Util {
    private static String byteArrayToHexString(byte[] b) {
        StringBuilder resultSb = new StringBuilder();
        for (byte value : b) {
            resultSb.append(byteToHexString(value));
        }
        return resultSb.toString();
    }

    private static String byteToHexString(byte b) {
        int n = b;
        if (n < 0) {
            n += 256;
        }
        int d1 = n / 16;
        int d2 = n % 16;
        return HEX_DIGITS[d1] + HEX_DIGITS[d2];
    }

    /**
     * 用UTF8編碼進(jìn)行MD5加密
     *
     * @param origin 原字符串
     * @return 加密后字符串
     */
    public static String md5Encode(String origin) {
        return md5Encode(origin, "UTF-8");
    }

    public static String md5Encode(String origin, String charsetname) {
        String resultString = null;
        try {
            resultString = origin;
            MessageDigest md = MessageDigest.getInstance("MD5");
            if (charsetname == null || "".equals(charsetname)) {
                resultString = byteArrayToHexString(md.digest(resultString.getBytes()));
            } else {
                resultString = byteArrayToHexString(md.digest(resultString.getBytes(charsetname)));
            }
        } catch (Exception ignored) {
        }
        return resultString;
    }

    private static final String[] HEX_DIGITS = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"};
}

以上就是Java實(shí)現(xiàn)MD5加密的四種方式的詳細(xì)內(nèi)容,更多關(guān)于Java MD5加密的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Swagger2不被SpringSecurity框架攔截的配置及說(shuō)明

    Swagger2不被SpringSecurity框架攔截的配置及說(shuō)明

    這篇文章主要介紹了Swagger2不被SpringSecurity框架攔截的配置及說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-03-03
  • springboot掃描自定義的servlet和filter代碼詳解

    springboot掃描自定義的servlet和filter代碼詳解

    本文是一篇根據(jù)作者工作經(jīng)歷總結(jié)出來(lái)的關(guān)于springboot掃描自定義的servlet和filter代碼詳解的文章,小編覺(jué)得非常不錯(cuò),這里給大家分享下,和朋友們一起學(xué)習(xí),進(jìn)步。
    2017-10-10
  • IDEA生成javadoc的實(shí)現(xiàn)步驟

    IDEA生成javadoc的實(shí)現(xiàn)步驟

    Javadoc是一種用于生成API文檔的工具,它可以根據(jù)代碼中特定格式的注釋自動(dòng)生成文檔,本文主要介紹了IDEA生成javadoc的實(shí)現(xiàn)步驟,感興趣的可以了解一下
    2023-10-10
  • java list 比較詳解及實(shí)例

    java list 比較詳解及實(shí)例

    這篇文章主要介紹了java list 比較詳解及實(shí)例的相關(guān)資料,需要的朋友可以參考下
    2017-05-05
  • SpringMVC使用@PathVariable接收參數(shù)過(guò)程解析

    SpringMVC使用@PathVariable接收參數(shù)過(guò)程解析

    這篇文章主要介紹了SpringMVC使用@PathVariable接收參數(shù)過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-10-10
  • TraceIdPatternLogbackLayout日志攔截源碼解析

    TraceIdPatternLogbackLayout日志攔截源碼解析

    這篇文章主要為大家介紹了TraceIdPatternLogbackLayout日志攔截源碼解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-11-11
  • 教你使用java實(shí)現(xiàn)去除各種空格

    教你使用java實(shí)現(xiàn)去除各種空格

    本文給大家匯總介紹了5種java中去除空格的方法,分別是String.trim()、str.replace(" ", "");、replaceAll(" +","");以及自定義的remove函數(shù),非常的簡(jiǎn)單實(shí)用,需要的小伙伴可以參考下。
    2015-03-03
  • Java中channel用法總結(jié)

    Java中channel用法總結(jié)

    這篇文章主要介紹了Java中channel用法,較為詳細(xì)的總結(jié)了channel的定義、類型及使用技巧,需要的朋友可以參考下
    2015-06-06
  • 詳解Spring 基于 Aspect 注解的增強(qiáng)實(shí)現(xiàn)

    詳解Spring 基于 Aspect 注解的增強(qiáng)實(shí)現(xiàn)

    本篇文章主要介紹了詳解Spring 基于 Aspect 注解的增強(qiáng)實(shí)現(xiàn),非常具有實(shí)用價(jià)值,需要的朋友可以參考下
    2017-04-04
  • groovy腳本定義結(jié)構(gòu)表一鍵生成POJO類

    groovy腳本定義結(jié)構(gòu)表一鍵生成POJO類

    這篇文章主要為大家介紹了groovy腳本定義結(jié)構(gòu)表一鍵生成POJO類示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-03-03

最新評(píng)論