Practical Implementation of MD5 Encryption Algorithm for File Integrity Verification

1. Basic Concepts

MD5 (Message-Digest Algorithm 5) is a widely used hash function that generates a 128-bit (16-byte) long “digital fingerprint” or hash value for each different file. This hash value can be seen as a unique identifier for the file, similar to an ID number. Its core function is to verify the integrity and authenticity of files, ensuring that they have not been tampered with during transmission or storage. Whether in software downloads, data transfers, or other scenarios requiring file integrity assurance, MD5 plays a crucial role.

2. Important Features

2.1 Avalanche Effect: The MD5 algorithm is highly sensitive; even a slight change in the file content will result in a significant change in the generated MD5 value. This feature allows for the quick identification of any unauthorized modifications to the file.

2.2 Irreversibility: The MD5 algorithm is a one-way hash function, meaning that the original file content cannot be derived from the MD5 value. This irreversibility ensures the privacy and security of the file content.

2.3 Uniqueness: In theory, different files are almost impossible to produce the same MD5 value. This high degree of uniqueness makes the MD5 value a reliable basis for verifying file integrity.

3. Basic Structure of the Algorithm

Input File → Chunk Processing → Four Rounds of Bitwise Operations → Concatenate Results → Generate 32-bit Hexadecimal Fingerprint

Practical Section (Java)

import java.io.File;import java.io.FileInputStream;import java.security.MessageDigest;import java.util.Scanner;public class EnhancedFileMD5Checker {    public static void main(String[] args) {        Scanner scanner = new Scanner(System.in);        System.out.println("=== File Integrity Verification Tool ===");        System.out.print("Please enter the file path to verify: ");        String filePath = scanner.nextLine().trim();        try {            // 1. Check if the file exists            File file = new File(filePath);            if (!file.exists() || !file.isFile()) {                System.err.println("Error: File does not exist or path is invalid");                return;            }            // 2. Get the original MD5 value from user input            System.out.print("Please enter the original MD5 value (32-bit hexadecimal): ");            String originalMD5 = scanner.nextLine().trim();            // 3. Verify MD5 format            if (!originalMD5.matches("[a-fA-F0-9]{32}")) {                System.err.println("Error: Invalid MD5 format, should be 32-bit hexadecimal characters");                return;            }            // 4. Calculate the file's MD5 value (with progress display)            System.out.println("\nStarting MD5 calculation, please wait...");            String calculatedMD5 = MD5HashUtil.calculateMD5Value(file);            // 5. Display results            System.out.println("\n===== Verification Results =====");            System.out.println("File Path: " + filePath);            System.out.println("File Size: " + formatFileSize(file.length()));            System.out.println("Calculated MD5: " + calculatedMD5);            System.out.println("Original MD5: " + originalMD5);            // 6. Integrity verification            if (originalMD5.equalsIgnoreCase(calculatedMD5)) {                System.out.println("\nFile integrity verification passed!");            } else {                System.out.println("\nFile has been tampered with or corrupted!");                System.out.println("Difference: " + findFirstDifference(originalMD5, calculatedMD5));            }        } catch (Exception e) {            System.err.println(" An error occurred: " + e.getMessage());        } finally {            scanner.close();        }    }    // Find the first difference position    private static String findFirstDifference(String original, String calculated) {        original = original.toLowerCase();        calculated = calculated.toLowerCase();        for (int i = 0; i < Math.min(original.length(), calculated.length()); i++) {            if (original.charAt(i) != calculated.charAt(i)) {                return String.format("Position %d: Original(%s) vs Calculated(%s)",                         i + 1, original.charAt(i), calculated.charAt(i));            }        }        return "No difference (same length but different content)";    }    // Format file size    private static String formatFileSize(long size) {        if (size < 1024) return size + " B";        int exp = (int) (Math.log(size) / Math.log(1024));        char unit = "KMGTPE".charAt(exp-1);        return String.format("%.2f %sB", size / Math.pow(1024, exp), unit);    }}
import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.IOException;import java.security.MessageDigest;import java.security.NoSuchAlgorithmException;public class MD5HashUtil {    /**     * Calculate MD5 hash value based on the file     * @param file     * @return     */        public static  String calculateMD5Value(File file){        try {            // Construct an MD5 object to encrypt the data                        MessageDigest md5 = MessageDigest.getInstance("MD5");            FileInputStream fileInputStream = new FileInputStream(file);            byte[] buffer = new byte[8192];            int read = -1;            while((read = fileInputStream.read(buffer)) != -1){                md5.update(buffer,0,read);            }            // Call the digest() method of the MD5 instance to generate a 16-byte (128-bit) hash value array, returning a byte array containing the hash value                    byte[] digest = md5.digest();            StringBuilder sb = new StringBuilder(32);            for (byte b : digest) {                // Convert byte to unsigned integer (0-255)                                sb.append(String.format("%02x",b &amp; 0xff));            }            return sb.toString();        } catch (FileNotFoundException e) {            throw new RuntimeException(e);        } catch (IOException e) {            throw new RuntimeException(e);        } catch (NoSuchAlgorithmException e) {            throw new RuntimeException(e);        }    }}

Execution Instructions

1. Preparation:

Create a test file test.txt (content can be arbitrary)

Compile and run: javac EnhancedFileMD5Checker.java && java EnhancedFileMD5Checker

2. Expected Output:

File Path: test.txt

Calculated MD5: 5d41402abc4b2a76b9719d911017c592

// Actual value depends on the original content of the file

MD5: 5d41402abc4b2a76b9719d911017c592

File integrity verification passed!

3. Verification of Tampering:

Modify the content of test.txt and run again

Observe the change in MD5 value and the verification failure prompt

Leave a Comment