2009-10-04 25 views
44

Estoy buscando una forma de obtener una suma de comprobación SHA-1 con una matriz de bytes Java como el mensaje.Computar SHA-1 de matriz de bytes

¿Debo usar una herramienta de terceros o hay algo incorporado en la JVM que pueda ayudar?

+11

que estaba buscando lo mismo. Una forma de calcular SHA1 en Java. ¿Lo que consigo? Dos respuestas Con mucho "esto está mal", "esto es horrible". Sin embargo, las personas que escribieron estos comentarios no escribieron una "buena" respuesta. – Shiki

Respuesta

46

¿Qué hay de:

import java.security.MessageDigest; 
import java.security.NoSuchAlgorithmException; 
import java.util.Formatter; 

public static String SHAsum(byte[] convertme) throws NoSuchAlgorithmException{ 
    MessageDigest md = MessageDigest.getInstance("SHA-1"); 
    return byteArray2Hex(md.digest(convertme)); 
} 

private static String byteArray2Hex(final byte[] hash) { 
    Formatter formatter = new Formatter(); 
    for (byte b : hash) { 
     formatter.format("%02x", b); 
    } 
    return formatter.toString(); 
} 
+1

Solo buscaba la manera de computar el sha1 - el formato no importa – Mike

+1

@jarnbjo Tienes razón, pero el OP no estaba pidiendo eso. –

+7

@PascalThivent Pero otro programador puede pasar por aquí y usar esta respuesta, incluido el error (después de todo, en parte se trata de SO). Hay suficiente vaguedad sobre hash como es (los documentos como "calcular esta firma mediante sha-1 hashing esta cadena concatenada", sin mencionar cómo codificar los caracteres de entrada y stringify la salida de hash, son bastante comunes). –

9

Este es un fragmento de código que utilizamos para convertir a SHA-1, pero toma un String en lugar de un Byte[] ver este javadoc para más información

 import java.io.UnsupportedEncodingException; 
     import java.security.MessageDigest; 
     import java.security.NoSuchAlgorithmException; 

     public class DoSHA1 { 

      private static String convToHex(byte[] data) { 
       StringBuilder buf = new StringBuilder(); 
       for (int i = 0; i < data.length; i++) { 
        int halfbyte = (data[i] >>> 4) & 0x0F; 
        int two_halfs = 0; 
        do { 
         if ((0 <= halfbyte) && (halfbyte <= 9)) 
          buf.append((char) ('0' + halfbyte)); 
         else 
          buf.append((char) ('a' + (halfbyte - 10))); 
         halfbyte = data[i] & 0x0F; 
        } while(two_halfs++ < 1); 
       } 
       return buf.toString(); 
      } 

      public static String SHA1(String text) throws NoSuchAlgorithmException, 
UnsupportedEncodingException { 
      MessageDigest md = MessageDigest.getInstance("SHA-1"); 
      byte[] sha1hash = new byte[40]; 
      md.update(text.getBytes("iso-8859-1"), 0, text.length()); 
      sha1hash = md.digest(); 
      return convToHex(sha1hash); 
      } 
     } 
+2

Si es lo suficientemente rápido para usted, también puede usar String.format ("% 02x", b) para convertir los bytes en una cadena hexadecimal. –

+0

La línea donde asigna una nueva matriz de 40 bytes es inútil; el objeto de matriz proviene de la llamada md.digest(). Cuando asigna la devolución de ese método a sha1hash, borra la matriz vacía de 40 bytes que ha creado. – MikeB

+0

Además, un compendio de SHA-1 es de 20 bytes, no de 40 bytes. – MikeB

8

Puede hágalo usted mismo o puede confiar en bibliotecas que han demostrado funcionar como Commons Codec. La clase DigestUtils tiene varios métodos para calcular los hashes ..

2

De CommonCodec DigestUtils Implementación del coversion Hex después del cálculo Digest como muestra antes:

MessageDigest md = MessageDigest.getInstance("SHA-1"); 
return byteArray2Hex(md.digest(convertme)); 

debería ser http://commons.apache.org/codec/apidocs/src-html/org/apache/commons/codec/binary/Hex.html#line.129:

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

private static final char[] DIGITS_UPPER = 
    {'0', '1', '2', '3', '4', '5', '6', '7', 
    '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; 

protected static char[] encodeHex(byte[] data, char[] toDigits) { 
    int l = data.length; 
    char[] out = new char[l << 1]; 
    // two characters form the hex value. 
    for (int i = 0, j = 0; i < l; i++) { 
     out[j++] = toDigits[(0xF0 & data[i]) >>> 4]; 
     out[j++] = toDigits[0x0F & data[i]]; 
    } 
    return out; 
} 

protected static int toDigit(char ch, int index) throws DecoderException { 
    int digit = Character.digit(ch, 16); 
    if (digit == -1) { 
     throw new DecoderException(
        "Illegal hexadecimal character " 
      + ch + " at index " + index); 
    } 
    return digit; 
} 

public static String exampleSha1(String convertme){ 
    MessageDigest md = MessageDigest.getInstance("SHA-1"); 
    byte[] encodeHex = md.digest(convertme)); 
    return new String(encodeHex); 
} 
1

.. Otra opción es utilizar Spring:

<bean id="passwordEncoder" class="org.springframework.security.authentication.encoding.ShaPasswordEncoder"> 
    <constructor-arg value="256"/> 
</bean> 

leer más here

HTH

+5

Es _amazing_ overhead :)) – ruX

0

Sólo he utilizado este para calcular la suma de hash dentro de un archivo de Dex y compararlo con el valor que se guarda en el archivo DEX.

, sé que este código no tiene muy buen estilo, pero es más PoC y solo se necesita para algunas investigaciones que no son críticas en el tiempo. ¡alguien puede usarlo!

class CheckDex{ 
public boolean checkSHA1(File f) throws IOException, NoSuchAlgorithmException{ 
    RandomAccessFile raf = new RandomAccessFile(f, "r"); 
    byte[] sig = new byte[20]; 
    raf.seek(0xC); 
    for(int i = 0; i < 20; i++){ 
     sig[i] = (byte) raf.readUnsignedByte(); 
    } 

    MessageDigest md = MessageDigest.getInstance("SHA-1"); 

    byte[] code = new byte[(int) (raf.length()-32)]; 
    for(int i = 0; i < code.length; i++){ 
     code[i] = (byte) raf.readUnsignedByte(); 
    } 
    byte[] comsig = md.digest(code); 

    raf.close(); 
    return Arrays.equals(sig,comsig); 
} 
} 
0

¿Qué tal el uso de este:

sha1Calculate public class {

public static void main(String[] args)throws Exception 
    { 
     File file = new File("D:\\Android Links.txt"); 
     String outputTxt= ""; 
     String hashcode = null; 

     try { 

      FileInputStream input = new FileInputStream(file); 

      ByteArrayOutputStream output = new ByteArrayOutputStream(); 
      byte [] buffer = new byte [65536]; 
      int l; 

      while ((l = input.read (buffer)) > 0) 
       output.write (buffer, 0, l); 

      input.close(); 
      output.close(); 

      byte [] data = output.toByteArray(); 


       MessageDigest digest = MessageDigest.getInstance("SHA-1"); 

      byte[] bytes = data; 

      digest.update(bytes, 0, bytes.length); 
      bytes = digest.digest(); 

      StringBuilder sb = new StringBuilder(); 

      for(byte b : bytes) 
      { 
       sb.append(String.format("%02X", b)); 
      } 

       System.out.println("Digest(in hex format):: " + sb.toString()); 


     }catch (FileNotFoundException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } catch (NoSuchAlgorithmException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 

    } 

}