encrypt - java security md5 hash
Obtención de la suma de comprobación MD5 de un archivo en Java (21)
Estoy buscando usar Java para obtener la suma de comprobación MD5 de un archivo. Me sorprendió mucho, pero no he podido encontrar nada que muestre cómo obtener la suma de comprobación MD5 de un archivo.
Como se hace
Aquí hay una función simple que envuelve el código de Sunil para que tome un archivo como parámetro. La función no necesita bibliotecas externas, pero sí requiere Java 7.
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import javax.xml.bind.DatatypeConverter;
public class Checksum {
/**
* Generates an MD5 checksum as a String.
* @param file The file that is being checksummed.
* @return Hex string of the checksum value.
* @throws NoSuchAlgorithmException
* @throws IOException
*/
public static String generate(File file) throws NoSuchAlgorithmException,IOException {
MessageDigest messageDigest = MessageDigest.getInstance("MD5");
messageDigest.update(Files.readAllBytes(file.toPath()));
byte[] hash = messageDigest.digest();
return DatatypeConverter.printHexBinary(hash).toUpperCase();
}
public static void main(String argv[]) throws NoSuchAlgorithmException, IOException {
File file = new File("/Users/foo.bar/Documents/file.jar");
String hex = Checksum.generate(file);
System.out.printf("hex=%s/n", hex);
}
}
Ejemplo de salida:
hex=B117DD0C3CBBD009AC4EF65B6D75C97B
Aquí hay una variación útil que hace uso de InputStream.transferTo()
de Java 9, y OutputStream.nullOutputStream()
de Java 11. No requiere bibliotecas externas y no necesita cargar todo el archivo en la memoria.
public static String hashFile(String algorithm, File f) throws IOException, NoSuchAlgorithmException {
MessageDigest md = MessageDigest.getInstance(algorithm);
try(BufferedInputStream in = new BufferedInputStream((new FileInputStream(f)));
DigestOutputStream out = new DigestOutputStream(OutputStream.nullOutputStream(), md)) {
in.transferTo(out);
}
String fx = "%0" + (md.getDigestLength()*2) + "x";
return String.format(fx, new BigInteger(1, md.digest()));
}
y
hashFile("SHA-512", Path.of("src", "test", "resources", "some.txt").toFile());
devoluciones
"e30fa2784ba15be37833d569280e2163c6f106506dfb9b07dde67a24bfb90da65c661110cf2c5c6f71185754ee5ae3fd83a5465c92f72abd888b03187229da29"
De acuerdo. Tuve que añadir. Implementación de una línea para aquellos que ya tienen la dependencia de Spring y Apache Commons o planean agregarla:
DigestUtils.md5DigestAsHex(FileUtils.readFileToByteArray(file))
Opción para y solo para los comunes de Apache (crédito @duleshi):
DigestUtils.md5Hex(FileUtils.readFileToByteArray(file))
Espero que esto ayude a alguien.
Estábamos usando un código que se parece al código anterior en una publicación anterior usando
...
String signature = new BigInteger(1,md5.digest()).toString(16);
...
Sin embargo, tenga cuidado con el uso de BigInteger.toString()
aquí, ya que truncará los ceros iniciales ... (para un ejemplo, intente s = "27"
, la suma de comprobación debería ser "02e74f10e0327ad868d138f2b4fdd6f0"
)
Respaldé la sugerencia de usar Apache Commons Codec, reemplazé nuestro propio código con eso.
Google guava proporciona una nueva API. Encuentra el siguiente:
public static HashCode hash(File file,
HashFunction hashFunction)
throws IOException
Computes the hash code of the file using hashFunction.
Parameters:
file - the file to read
hashFunction - the hash function to use to hash the data
Returns:
the HashCode of all of the bytes in the file
Throws:
IOException - if an I/O error occurs
Since:
12.0
Hace poco tuve que hacer esto solo para una cadena dinámica, MessageDigest
puede representar el hash de varias maneras. Para obtener la firma del archivo como lo haría con el comando md5sum , tuve que hacer algo como esto:
try {
String s = "TEST STRING";
MessageDigest md5 = MessageDigest.getInstance("MD5");
md5.update(s.getBytes(),0,s.length());
String signature = new BigInteger(1,md5.digest()).toString(16);
System.out.println("Signature: "+signature);
} catch (final NoSuchAlgorithmException e) {
e.printStackTrace();
}
Obviamente, esto no responde a su pregunta sobre cómo hacerlo específicamente para un archivo, la respuesta anterior aborda muy bien esa tranquilidad. Acabo de pasar mucho tiempo haciendo que la suma se vea como la mayoría de las aplicaciones lo muestran, y pensé que podría tener los mismos problemas.
Hay un ejemplo en Java''s How-to de Real usando la clase MessageDigest .
Verifique en esa página los ejemplos que usan CRC32 y SHA-1 también.
import java.io.*;
import java.security.MessageDigest;
public class MD5Checksum {
public static byte[] createChecksum(String filename) throws Exception {
InputStream fis = new FileInputStream(filename);
byte[] buffer = new byte[1024];
MessageDigest complete = MessageDigest.getInstance("MD5");
int numRead;
do {
numRead = fis.read(buffer);
if (numRead > 0) {
complete.update(buffer, 0, numRead);
}
} while (numRead != -1);
fis.close();
return complete.digest();
}
// see this How-to for a faster way to convert
// a byte array to a HEX string
public static String getMD5Checksum(String filename) throws Exception {
byte[] b = createChecksum(filename);
String result = "";
for (int i=0; i < b.length; i++) {
result += Integer.toString( ( b[i] & 0xff ) + 0x100, 16).substring( 1 );
}
return result;
}
public static void main(String args[]) {
try {
System.out.println(getMD5Checksum("apache-tomcat-5.5.17.exe"));
// output :
// 0bb2827c5eacf570b6064e24e0e6653b
// ref :
// http://www.apache.org/dist/
// tomcat/tomcat-5/v5.5.17/bin
// /apache-tomcat-5.5.17.exe.MD5
// 0bb2827c5eacf570b6064e24e0e6653b *apache-tomcat-5.5.17.exe
}
catch (Exception e) {
e.printStackTrace();
}
}
}
La API com.google.common.hash ofrece:
- Una API unificada y fácil de usar para todas las funciones hash
- Implementaciones de 32 y 128 bits sembradas de murmur3
- md5 (), sha1 (), sha256 (), sha512 () adaptadores, cambie solo una línea de código para cambiar entre estos, y murmure.
- goodFastHash (int bits), para cuando no te importa qué algoritmo usas
- Utilidades generales para instancias de HashCode, como combineOrdered / combineUnordered
Lea la Guía del usuario ( Explicación de E / S , Explicación de hash ).
Para su caso de uso, Files.hash()
calcula y devuelve el valor de resumen de un archivo.
Por ejemplo, un cálculo de resumen de sha-1 (cambie SHA-1 a MD5 para obtener un resumen de MD5)
HashCode hc = Files.asByteSource(file).hash(Hashing.sha1());
"SHA-1: " + hc.toString();
Tenga en cuenta que crc32 es mucho más rápido que md5 , así que use crc32 si no necesita una suma de comprobación criptográficamente segura. Tenga en cuenta también que md5 no debe utilizarse para almacenar contraseñas y similares, ya que es fácil de forzar la fuerza bruta, ya que las contraseñas usan bcrypt , scrypt o sha-256 lugar.
Para protección a largo plazo con hash, un esquema de firmas Merkle se suma a la seguridad y el Grupo de Estudio de Criptografía Post Quantum patrocinado por la Comisión Europea ha recomendado el uso de esta criptografía para protección a largo plazo contra computadoras cuánticas ( ref ).
Tenga en cuenta que crc32 tiene una tasa de colisión más alta que las otras.
Método Java muy rápido y limpio que no depende de bibliotecas externas:
(Simplemente reemplace el MD5 con SHA-1, SHA-256, SHA-384 o SHA-512 si lo desea)
public String calcMD5() throws Exception{
byte[] buffer = new byte[8192];
MessageDigest md = MessageDigest.getInstance("MD5");
DigestInputStream dis = new DigestInputStream(new FileInputStream(new File("Path to file")), md);
try {
while (dis.read(buffer) != -1);
}finally{
dis.close();
}
byte[] bytes = md.digest();
// bytesToHex-method
char[] hexChars = new char[bytes.length * 2];
for ( int j = 0; j < bytes.length; j++ ) {
int v = bytes[j] & 0xFF;
hexChars[j * 2] = hexArray[v >>> 4];
hexChars[j * 2 + 1] = hexArray[v & 0x0F];
}
return new String(hexChars);
}
Otra implementación: Implementación rápida de MD5 en Java
String hash = MD5.asHex(MD5.getHash(new File(filename)));
Si estás usando ANT para construir, esto es muy simple. Agregue lo siguiente a su build.xml:
<checksum file="${jarFile}" todir="${toDir}"/>
Donde jarFile es el JAR contra el que desea generar el MD5, y toDir es el directorio donde desea colocar el archivo MD5.
Un enfoque simple sin bibliotecas de terceros utilizando Java 7
String path = "your complete file path";
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(Files.readAllBytes(Paths.get(path)));
byte[] digest = md.digest();
Si necesita imprimir esta matriz de bytes. Usar como abajo
System.out.println(Arrays.toString(digest));
Si necesitas una cadena hexagonal fuera de este compendio. Usar como abajo
String digestInHex = DatatypeConverter.printHexBinary(digest).toUpperCase();
System.out.println(digestInHex);
donde DatatypeConverter es javax.xml.bind.DatatypeConverter
Usando nio2 (Java 7+) y sin bibliotecas externas:
byte[] b = Files.readAllBytes(Paths.get("/path/to/file"));
byte[] hash = MessageDigest.getInstance("MD5").digest(b);
Para comparar el resultado con una suma de comprobación esperada:
String expected = "2252290BC44BEAD16AA1BF89948472E8";
String actual = DatatypeConverter.printHexBinary(hash);
System.out.println(expected.equalsIgnoreCase(actual) ? "MATCH" : "NO MATCH");
Utilice DigestUtils de la biblioteca DigestUtils de Apache Commons :
FileInputStream fis = new FileInputStream(new File("foo"));
String md5 = org.apache.commons.codec.digest.DigestUtils.md5Hex(fis);
fis.close();
Guava ahora proporciona una nueva API de hashing coherente que es mucho más fácil de usar que las diversas API de hashing proporcionadas en el JDK. Ver Hashing explicado . Para un archivo, puede obtener la suma MD5, CRC32 (con versión 14.0+) o muchos otros hashes fácilmente:
HashCode md5 = Files.hash(file, Hashing.md5());
byte[] md5Bytes = md5.asBytes();
String md5Hex = md5.toString();
HashCode crc32 = Files.hash(file, Hashing.crc32());
int crc32Int = crc32.asInt();
// the Checksum API returns a long, but it''s padded with 0s for 32-bit CRC
// this is the value you would get if using that API directly
long checksumResult = crc32.padToLong();
Forma estándar de Java Runtime Environment :
public String checksum(File file) {
try {
InputStream fin = new FileInputStream(file);
java.security.MessageDigest md5er =
MessageDigest.getInstance("MD5");
byte[] buffer = new byte[1024];
int read;
do {
read = fin.read(buffer);
if (read > 0)
md5er.update(buffer, 0, read);
} while (read != -1);
fin.close();
byte[] digest = md5er.digest();
if (digest == null)
return null;
String strDigest = "0x";
for (int i = 0; i < digest.length; i++) {
strDigest += Integer.toString((digest[i] & 0xff)
+ 0x100, 16).substring(1).toUpperCase();
}
return strDigest;
} catch (Exception e) {
return null;
}
}
El resultado es igual a la utilidad linux md5sum.
Hay un decorador de flujo de entrada, java.security.DigestInputStream
, para que pueda calcular el compendio mientras usa el flujo de entrada como lo haría normalmente, en lugar de tener que hacer un pase adicional sobre los datos.
MessageDigest md = MessageDigest.getInstance("MD5");
try (InputStream is = Files.newInputStream(Paths.get("file.txt"));
DigestInputStream dis = new DigestInputStream(is, md))
{
/* Read decorated stream (dis) to EOF as normal... */
}
byte[] digest = md.digest();
String checksum = DigestUtils.md5Hex(new FileInputStream(filePath));
public static String MD5Hash(String toHash) throws RuntimeException {
try{
return String.format("%032x", // produces lower case 32 char wide hexa left-padded with 0
new BigInteger(1, // handles large POSITIVE numbers
MessageDigest.getInstance("MD5").digest(toHash.getBytes())));
}
catch (NoSuchAlgorithmException e) {
// do whatever seems relevant
}
}
public static String getMd5OfFile(String filePath)
{
String returnVal = "";
try
{
InputStream input = new FileInputStream(filePath);
byte[] buffer = new byte[1024];
MessageDigest md5Hash = MessageDigest.getInstance("MD5");
int numRead = 0;
while (numRead != -1)
{
numRead = input.read(buffer);
if (numRead > 0)
{
md5Hash.update(buffer, 0, numRead);
}
}
input.close();
byte [] md5Bytes = md5Hash.digest();
for (int i=0; i < md5Bytes.length; i++)
{
returnVal += Integer.toString( ( md5Bytes[i] & 0xff ) + 0x100, 16).substring( 1 );
}
}
catch(Throwable t) {t.printStackTrace();}
return returnVal.toUpperCase();
}
public static void main(String[] args) throws Exception {
MessageDigest md = MessageDigest.getInstance("MD5");
FileInputStream fis = new FileInputStream("c://apache//cxf.jar");
byte[] dataBytes = new byte[1024];
int nread = 0;
while ((nread = fis.read(dataBytes)) != -1) {
md.update(dataBytes, 0, nread);
};
byte[] mdbytes = md.digest();
StringBuffer sb = new StringBuffer();
for (int i = 0; i < mdbytes.length; i++) {
sb.append(Integer.toString((mdbytes[i] & 0xff) + 0x100, 16).substring(1));
}
System.out.println("Digest(in hex format):: " + sb.toString());
}
O puede obtener más información http://www.asjava.com/core-java/java-md5-example/