GhostCat
GhostCat

Reputation: 140613

SHA512 hashing gives incorrect (?) results when "salted"

I want to implement SHA512 hashing using a salt. I started here, leading to this mcve:

import java.security.MessageDigest;
import org.junit.Test;

public class Sha512Mcve {

    private final String ENCODING = "ISO-8859-1";

    @Test
    public void test() {
        System.out.println(computeHashFor("whatever"));
    }

    private String computeHashFor(String toHash) {
        String salt = "salt";
        MessageDigest md;
        try {
            md = MessageDigest.getInstance("SHA-512");
//          md.update(salt.getBytes(ENCODING));
            byte[] bytes = md.digest(toHash.getBytes(ENCODING));

            return toUnixRepresentation(salt, bytes);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    private String toUnixRepresentation(String salt, byte[] bytes) {
        StringBuilder sb = new StringBuilder();
        sb.append("$6$");
        sb.append(salt);
        sb.append("$");

        for (int i = 0; i < bytes.length; i++) {
            int c = bytes[i] & 0xFF;
            if (c < 16) sb.append("0");
            sb.append(Integer.toHexString(c));
        }
        return sb.toString();
    }
}

Thing is: when I leave the line md.update() commented out, this code gives me the exact same results as some online hash generators (like this one).

For example, hashing the word "whatever" gives a hash value ae3d....63a.

But when I run my code with that salt operation; I get different results (again compared against that online tool, which allows to set a salt string, too).

My implementation results in 413...623; the online tool says F25...686.

Any explanation in which way "salting" leads to "implementation specific" results?

Is there something I should do differently in my code?

Upvotes: 2

Views: 710

Answers (1)

hakamairi
hakamairi

Reputation: 4678

Salt before or after?

What the calculator does when you set the salt option

whateversalt

What you are doing in your code

saltwhatever

resutls from the calculator

whateversalt

F2527142C752B05467EE53B44735397F5B4C870DF0F154A0CF3AC23B31CF42EE7E1002D326B57DF60ED4B7449CF101290BDC0BECCB677AAAD846CFBE140DF686

saltwhatever

41333B9BAFC14CB3D1106D72A5D461F348B9EA1304A82989E00E5FC2D3239339492FCA12ED5EBF5F6802955C95B5F7ADA4CA035A911C2F29ABE905C3923CF623

Therefore to match the calculation you just have to reverse the order and add the salt last

        md.update(toHash.getBytes(ENCODING));
        byte[] bytes = md.digest(salt.getBytes(ENCODING));

Or even

        md.update(toHash.getBytes(ENCODING));
        md.update(salt.getBytes(ENCODING));
        byte[] bytes = md.digest();

Upvotes: 4

Related Questions