本文主要介绍Java中,使用MD5、SHA1、SHA-256和SHA-512算法来计算文件和字符串的哈希值(hash)的方法,以及相关使用的示例方法代码。

1、计算文件哈希值(hash) Hash

package com.memorynotfound.file;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.security.MessageDigest;
public enum Hash {
MD5("MD5"),
SHA1("SHA1"),
SHA256("SHA-256"),
SHA512("SHA-512");
private String name;
Hash(String name) {
this.name = name;
}
public String getName() {
return name;
}
public byte[] checksum(File input) {
try (InputStream in = new FileInputStream(input)) {
MessageDigest digest = MessageDigest.getInstance(getName());
byte[] block = new byte[4096];
int length;
while ((length = in.read(block)) > 0) {
digest.update(block, 0, length);
}
return digest.digest();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}

使用示例代码:

package com.memorynotfound.file;
import javax.xml.bind.DatatypeConverter;
import java.io.File;
public class FileChecksumExample {
public static void main(String[] args) throws Exception {
File file = new File("/tmp/cjavapy.pdf");
System.out.println("MD5 : " + toHex(Hash.MD5.checksum(file)));
System.out.println("SHA1 : " + toHex(Hash.SHA1.checksum(file)));
System.out.println("SHA256 : " + toHex(Hash.SHA256.checksum(file)));
System.out.println("SHA512 : " + toHex(Hash.SHA512.checksum(file)));
}
private static String toHex(byte[] bytes) {
return DatatypeConverter.printHexBinary(bytes);
}
}

2、计算字符串哈希值(hash) Hash

盐(Salt): 在密码学中,是指通过在密码任意固定位置插入特定的字符串,让散列后的结果和使用原始密码的散列结果不相符,这种过程称之为“加盐”。

1) 使用MD5计算

public class SimpleMD5Example 
{
    public static void main(String[] args) 
    {
        String passwordToHash = "password";
        String generatedPassword = null;
        try {
            // 为MD5创建MessageDigest实例
            MessageDigest md = MessageDigest.getInstance("MD5");
            //添加密码字节以进行
            md.update(passwordToHash.getBytes());
            //Get the hash's bytes 
            byte[] bytes = md.digest();
            //This bytes[] has bytes in decimal format;
            //将其转换为十六进制格式
            StringBuilder sb = new StringBuilder();
            for(int i=0; i< bytes.length ;i++)
            {
                sb.append(Integer.toString((bytes[i] & 0xff) + 0x100, 16).substring(1));
            }
            //得到完整的哈希密码在十六进制格式
            generatedPassword = sb.toString();
        } 
        catch (NoSuchAlgorithmException e) 
        {
            e.printStackTrace();
        }
        System.out.println(generatedPassword);
    }
}

输出:

5f4dcc3b5aa765d61d8327deb882cf99 

2) 使用SHA1计算

package com.cjavapy.hashing.password.demo.sha;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
public class SHAExample {
    public static void main(String[] args) throws NoSuchAlgorithmException 
    {
        String passwordToHash = "password";
        byte[] salt = getSalt();
        String securePassword = get_SHA_SecurePassword(passwordToHash, salt);
        System.out.println(securePassword);
    }
    private static String get_SHA_SecurePassword(String passwordToHash, byte[] salt)
    {
        String generatedPassword = null;
        try {
            MessageDigest md = MessageDigest.getInstance("SHA-1");
            //MessageDigest md = MessageDigest.getInstance("SHA-256");
            //MessageDigest md = MessageDigest.getInstance("SHA-512");
            md.update(salt);
            byte[] bytes = md.digest(passwordToHash.getBytes());
            StringBuilder sb = new StringBuilder();
            for(int i=0; i< bytes.length ;i++)
            {
                sb.append(Integer.toString((bytes[i] & 0xff) + 0x100, 16).substring(1));
            }
            generatedPassword = sb.toString();
        } 
        catch (NoSuchAlgorithmException e) 
        {
            e.printStackTrace();
        }
        return generatedPassword;
    }    
    //Add salt
    private static byte[] getSalt() throws NoSuchAlgorithmException
    {
        SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
        byte[] salt = new byte[16];
        sr.nextBytes(salt);
        return salt;
    }
}

输出:

1)SHA1:

e4c53afeaa7a08b1f27022abd443688c37981bc4

2)SHA256:

87adfd14a7a89b201bf6d99105b417287db6581d8aee989076bb7f86154e8f32

3)SHA512:

529211542985b8f7af61994670d03d25d55cc9cd1cff8d57bb799c4b586891e112b197530c76744bcd7ef135b58d47d65a0bec221eb5d77793956cf2709dd012

参考文档:

hash-md5-sha-pbkdf2-bcrypt-examples

calculate-file-checksum-java