Compute SHA-1 of byte array

JavaSha1

Java Problem Overview


I'm looking for a way of getting an SHA-1 checksum with a Java byte array as the message.

Should I use a third party tool or is there something built in to the JVM that can help?

Java Solutions


Solution 1 - Java

What about:

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

Solution 2 - Java

You can do it yourself but I would recommend to use a library that has been proven to work, like Commons Codec. The class DigestUtils has several methods to calculate hashes.

Solution 3 - Java

This a snippet of code we use to convert to SHA-1 but takes a String instead of a Byte[] see this javadoc for further info

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

Solution 4 - Java

From CommonCodec DigestUtils Implementation the Hex coversion after the Digest calculation as shown before :

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

should be 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);
}

Solution 5 - Java

...another option is to use Spring:

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

read more here

HTH

Solution 6 - Java

I Just used this to compute the hash sum inside of a dex file and compare it with the value which is saved in the dex file.

i know this code hasnt very good style but its more PoC and only needed for some research which isnt time critical. may someone can use it!

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

Solution 7 - Java

How about Using This:

public class sha1Calculate {

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

    }
    
}

Solution 8 - Java

The following code converts the given byte[] into a String of the SHA-1 hash.

import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public static String hash(byte data[]) throws NoSuchAlgorithmException
{
   MessageDigest digest;
   BigInteger big;
   String result;
   byte hash[];

   digest = MessageDigest.getInstance("SHA-1"); 
   hash   = digest.digest(data);
   big    = new BigInteger(1, hash);
   result = big.toString(16);

   return result;
}

Note: The leading zeros will be trimmed. So, this may or may not work depending on your use case.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMikeView Question on Stackoverflow
Solution 1 - JavaPascal ThiventView Answer on Stackoverflow
Solution 2 - JavaJashaView Answer on Stackoverflow
Solution 3 - Javanon sequitorView Answer on Stackoverflow
Solution 4 - JavaloreiiView Answer on Stackoverflow
Solution 5 - JavaOhadRView Answer on Stackoverflow
Solution 6 - JavareoxView Answer on Stackoverflow
Solution 7 - JavaNayan RathView Answer on Stackoverflow
Solution 8 - JavaNathanView Answer on Stackoverflow