2009-10-04 5 views
44

Je suis à la recherche d'un moyen d'obtenir une somme de contrôle SHA-1 avec un tableau d'octets Java comme message. Dois-je utiliser un outil tiers ou y a-t-il quelque chose de intégré à la JVM qui peut aider?Calculer SHA-1 du tableau d'octets

+11

Je cherchais la même chose. Un moyen de calculer SHA1 en Java. Qu'est-ce que je reçois? Deux réponses Avec beaucoup de "c'est faux", "c'est horrible". Pourtant, les personnes qui ont écrit ces commentaires n'ont pas écrit une «bonne» réponse. – Shiki

Répondre

46

Qu'en est-:

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

Je cherchais seulement le moyen de calculer le sha1 - le format n'a pas d'importance – Mike

+1

@jarnbjo Vous avez raison, mais l'OP ne le demandait pas. –

+7

@PascalThivent Mais un autre programmeur peut s'arrêter et utiliser cette réponse, y compris l'erreur (après tout, c'est en partie ce qu'est le SO). Il y a assez de vague sur le hachage tel qu'il est (docs comme "calculer cette signature par sha-1 hacher ces chaînes concaténées", sans mentionner comment encoder les caractères d'entrée et stringifier la sortie de hachage, sont assez communs). –

9

Cet un extrait de code que nous utilisons pour convertir en SHA-1, mais prend un String au lieu d'un Byte[] voir ce javadoc pour plus d'informations

 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 c'est assez rapide pour vous, vous pouvez aussi utiliser String.format ("% 02x", b) pour convertir les octets en une chaîne hexadécimale. –

+0

La ligne sur laquelle vous allouez un nouveau tableau de 40 octets est inutile; l'objet tableau provient de l'appel de md.digest(). Lorsque vous affectez le retour de cette méthode à sha1hash, vous effacez le tableau vide de 40 octets que vous avez créé. – MikeB

+0

En outre, un condensé SHA-1 est 20 octets, pas 40 octets. – MikeB

8

Vous pouvez faites-le vous-même ou vous pouvez compter sur des bibliothèques qui ont fait leurs preuves comme Commons Codec. La classe DigestUtils a plusieurs méthodes pour calculer hash ..

2

De CommonCodec DigestUtils La mise en œuvre du Hex coversion après le calcul Digest comme indiqué précédemment:

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

devrait être 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

.. une autre option est d'utiliser le printemps:

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

lire la suite here

HTH

+5

C'est _amazing_ frais généraux :)) – ruX

0

Je viens d'utiliser cela pour calculer la somme de hachage à l'intérieur d'un fichier dex et le comparer avec la valeur qui est enregistrée dans le fichier Dex.

Je sais que ce code n'a pas un très bon style mais son plus de PoC et seulement nécessaire pour certaines recherches qui ne sont pas critiques dans le temps. Que quelqu'un puisse l'utiliser!

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

Que diriez-vous d'utiliser ce:

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(); 
    } 

    } 

}