Bouncy Castle Sha3 wrong output?

2019-05-01 15:10发布

I'm working on a JAVA project that needs to perform a sha3-256 hash. Since Bouncy Castle implemented Sha3 in its latest update, I plan to use their implementation. Here is my code:

 public static String sha3(final String input) {

    String hash = "";

    final SHA3.DigestSHA3 md = new SHA3.DigestSHA3(256);
    md.update(input.getBytes());
    hash = Main2.toString(md.digest());

    return hash;
  }

When running System.out.println(Main2.sha3(""));, I get the following output:

C5D2460186F7233C927E7DB2DCC703C0E500B653CA82273B7BFAD8045D85A470

When I search fot basic sha3 outputs from: wikipedia: https://en.wikipedia.org/wiki/SHA-3
or NIST standards: http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/SHA3-256_Msg0.pdf , it seems I should obtain:

a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a

Is there any mistake in my code? Any link between bouncy castle's output and NIST's? Would there be a mistake in bouncy castle's implementation?

Thanks for your time and regards.

4条回答
女痞
2楼-- · 2019-05-01 15:13

I guess you have wrong logic of Main2.toString. And the Main2.toString shall to transform byte[] to hex string.

Here is one implementation:

final protected static char[] hexArray = "0123456789ABCDEF".toCharArray();
public static String bytesToHex(byte[] bytes) {
    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);
}

I have tried your code, the output is :

A7FFC6F8BF1ED76651C14756A061D662F580FF4DE43B49FA82D80A4B80F8434A

/**
 * Created by chenzhongpu on 19/10/2015.
 */
import org.bouncycastle.jcajce.provider.digest.*;
public class TestSHA3 {
    final protected static char[] hexArray = "0123456789ABCDEF".toCharArray();
    public static String bytesToHex(byte[] bytes) {
        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);
    }
    public static String sha3(final String input){
        String hash = "";
        SHA3.DigestSHA3 md = new SHA3.DigestSHA3(256);
        md.update(input.getBytes());
        hash = bytesToHex(md.digest());
        return hash;

    }
    public static void main(String[] args) {
        System.out.println(sha3(""));
    }
}
查看更多
地球回转人心会变
3楼-- · 2019-05-01 15:17

No need to create custom method to convert byteArray into String, use the inbuilt function

public static String hashPassword(String password) {

    DigestSHA3 md = new DigestSHA3(256);
    md.update(password.getBytes());
    byte[] digest = md.digest();
    return Hex.toHexString(digest);
}

the maven entries are

    <!-- https://mvnrepository.com/artifact/org.bouncycastle/bcprov-jdk15on -->
    <dependency>
        <groupId>org.bouncycastle</groupId>
        <artifactId>bcprov-jdk15on</artifactId>
        <version>1.56</version>
    </dependency>
查看更多
做自己的国王
4楼-- · 2019-05-01 15:26

Your SHA3 should be computed correctly.

You have an issue with the code in your question:

  • You have not provided Main2.toString(String)

The following hashes and transforms the bytes into a hexadecimal string:

import java.security.MessageDigest;

import org.bouncycastle.jcajce.provider.digest.SHA3.DigestSHA3;
import org.bouncycastle.jcajce.provider.digest.SHA3.Digest256;

public class TestSha3 {
    public static void main(String[] args) {
        System.out.println(sha3(""));
    }

    public static String sha3(final String input) {
        final DigestSHA3 sha3 = new Digest256();

        sha3.update(input.getBytes());

        return TestSha3.hashToString(sha3);
    }

    public static String hashToString(MessageDigest hash) {
        return hashToString(hash.digest());
    }

    public static String hashToString(byte[] hash) {
        StringBuffer buff = new StringBuffer();

        for (byte b : hash) {
            buff.append(String.format("%02x", b & 0xFF));
        }

        return buff.toString();
    }
}

Output

a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a

I used the following artifact in my Maven build

<dependency>
    <groupId>org.bouncycastle</groupId>
    <artifactId>bcprov-jdk15on</artifactId>
    <version>1.53</version>
</dependency>
查看更多
Melony?
5楼-- · 2019-05-01 15:33

The problem with bouncy castle library versions If you are use bouncy castle 1.50 library(input: SHA3-256("")) output of bouncy does not match with NIST output.

Use bouncy castle 1.54 version Output from bouncy is equal to NIST example values(Example values in https://en.wikipedia.org/wiki/SHA-3 )

Thanks

查看更多
登录 后发表回答