在用Java编程SHA-256时我做错了什么?

时间:2017-01-21 09:12:14

标签: java hash cryptography sha256

我正在关注官方的NIST文档,但我无法获得与Java内置的MessageDigest类相同的结果。例如,字符串"这用于测试SHA-2"在此程序中生成00c4f24db568535c8e00fe22f51200b6f3c600601dd8d749cfd9b91ac2307300afe39444。在MessageDigest类中,它是32553c5e02e27bdcc4bf72210d7f07be2ad1e27f6c253e75608722322172062d。我犯了什么错误吗?

public class SHA_256 {

private byte[] data;
private byte[] padded;
private int blocks;
final private int word_size = 32;
final private BigInteger modulo = BigInteger.valueOf(2).pow(word_size);
private BigInteger m[][];
private BigInteger w[] = new BigInteger[64];
private BigInteger k[] = new BigInteger[64];
private BigInteger h0;
private BigInteger h1;
private BigInteger h2;
private BigInteger h3;
private BigInteger h4;
private BigInteger h5;
private BigInteger h6;
private BigInteger h7;
private byte[] digest;

public SHA_256() {
    initConstants();
}

public SHA_256(byte[] input) throws IOException {
    initConstants();
    computeHash(input);
}

private void initConstants() {
    k[0] = new BigInteger("428a2f98", 32);
    k[1] = new BigInteger("71374491", 32);
    k[2] = new BigInteger("b5c0fbcf", 32);
    k[3] = new BigInteger("e9b5dba5", 32);
    k[4] = new BigInteger("3956c25b", 32);
    k[5] = new BigInteger("59f111f1", 32);
    k[6] = new BigInteger("923f82a4", 32);
    k[7] = new BigInteger("ab1c5ed5", 32);
    k[8] = new BigInteger("d807aa98", 32);
    k[9] = new BigInteger("12835b01", 32);
    k[10] = new BigInteger("243185be", 32);
    k[11] = new BigInteger("550c7dc3", 32);
    k[12] = new BigInteger("72be5d74", 32);
    k[13] = new BigInteger("80deb1fe", 32);
    k[14] = new BigInteger("9bdc06a7", 32);
    k[15] = new BigInteger("c19bf174", 32);
    k[16] = new BigInteger("e49b69c1", 32);
    k[17] = new BigInteger("efbe4786", 32);
    k[18] = new BigInteger("0fc19dc6", 32);
    k[19] = new BigInteger("240ca1cc", 32);
    k[20] = new BigInteger("2de92c6f", 32);
    k[21] = new BigInteger("4a7484aa", 32);
    k[22] = new BigInteger("5cb0a9dc", 32);
    k[23] = new BigInteger("76f988da", 32);
    k[24] = new BigInteger("983e5152", 32);
    k[25] = new BigInteger("a831c66d", 32);
    k[26] = new BigInteger("b00327c8", 32);
    k[27] = new BigInteger("bf597fc7", 32);
    k[28] = new BigInteger("c6e00bf3", 32);
    k[29] = new BigInteger("d5a79147", 32);
    k[30] = new BigInteger("06ca6351", 32);
    k[31] = new BigInteger("14292967", 32);
    k[32] = new BigInteger("27b70a85", 32);
    k[33] = new BigInteger("2e1b2138", 32);
    k[34] = new BigInteger("4d2c6dfc", 32);
    k[35] = new BigInteger("53380d13", 32);
    k[36] = new BigInteger("650a7354", 32);
    k[37] = new BigInteger("766a0abb", 32);
    k[38] = new BigInteger("81c2c92e", 32);
    k[39] = new BigInteger("92722c85", 32);
    k[40] = new BigInteger("a2bfe8a1", 32);
    k[41] = new BigInteger("a81a664b", 32);
    k[42] = new BigInteger("c24b8b70", 32);
    k[43] = new BigInteger("c76c51a3", 32);
    k[44] = new BigInteger("d192e819", 32);
    k[45] = new BigInteger("d6990624", 32);
    k[46] = new BigInteger("f40e3585", 32);
    k[47] = new BigInteger("106aa070", 32);
    k[48] = new BigInteger("19a4c116", 32);
    k[49] = new BigInteger("1e376c08", 32);
    k[50] = new BigInteger("2748774c", 32);
    k[51] = new BigInteger("34b0bcb5", 32);
    k[52] = new BigInteger("391c0cb3", 32);
    k[53] = new BigInteger("4ed8aa4a", 32);
    k[54] = new BigInteger("5b9cca4f", 32);
    k[55] = new BigInteger("682e6ff3", 32);
    k[56] = new BigInteger("748f82ee", 32);
    k[57] = new BigInteger("78a5636f", 32);
    k[58] = new BigInteger("84c87814", 32);
    k[59] = new BigInteger("8cc70208", 32);
    k[60] = new BigInteger("90befffa", 32);
    k[61] = new BigInteger("a4506ceb", 32);
    k[62] = new BigInteger("bef9a3f7", 32);
    k[63] = new BigInteger("c67178f2", 32);
}

private void initHashValues() {
    h0 = new BigInteger("6a09e667", 32);
    h1 = new BigInteger("bb67ae85", 32);
    h2 = new BigInteger("3c6ef372", 32);
    h3 = new BigInteger("a54ff53a", 32);
    h4 = new BigInteger("510e527f", 32);
    h5 = new BigInteger("9b05688c", 32);
    h6 = new BigInteger("1f83d9ab", 32);
    h7 = new BigInteger("5be0cd19", 32);
}

private void padding() {
    if (data.length % 64 < 56) {
        padded = new byte[64*(data.length/64 + 1)];
        System.arraycopy(data, 0, padded, 0, data.length);
        padded[data.length] = (byte) 0b10000000;
    }
    else {
        padded = new byte[64*(data.length/64 + 2)];
        System.arraycopy(data, 0, padded, 0, data.length);
        padded[data.length] = (byte) 0b10000000;
    }
    byte[] length = new byte[8]; //64-bit representation of the length of the data
    ByteBuffer.wrap(length).putInt(data.length);
    System.arraycopy(length, 0, padded, padded.length - 9, length.length);
    blocks = padded.length/64;
}

private void parsing() {
    m = new BigInteger[blocks][16];
    int index = 0;
    byte[] word = new byte[4];
    for (int i = 0; i < blocks; i++) {
        for (int j = 0; j < 16; j++) {
            System.arraycopy(padded, index, word, 0, 4);
            m[i][j] = new BigInteger(word);
            index += 4;
        }
    }
}

public void computeHash(byte[] input) throws IOException {
    data = input;
    initHashValues();
    padding();
    parsing();

    for (int i = 0; i < blocks; i++) {
        for (int t = 0; t < 64; t++) {
            if (t <= 15) {
                w[t] = m[i][t];
            }
            else {
                w[t] = add(l_sigma1(w[t-2]), w[t-7]);
                w[t] = add(w[t], l_sigma0(w[t-15]));
                w[t] = add(w[t], w[t-16]);
            }
        }

        BigInteger a = h0;
        BigInteger b = h1;
        BigInteger c = h2;
        BigInteger d = h3;
        BigInteger e = h4;
        BigInteger f = h5;
        BigInteger g = h6;
        BigInteger h = h7;

        BigInteger t1;
        BigInteger t2;

        for (int t = 0; t < 64; t++) {
            t1 = add(h, sigma1(e));
            t1 = add(t1, ch(e, f, g));
            t1 = add(t1, k[t]);
            t1 = add(t1, w[t]);
            t2 = add(sigma0(a), maj(a, b, c));
            h = g;
            g = f;
            f = e;
            e = add(d, t1);
            d = c;
            c = b;
            b = a;
            a = add(t1, t2);
        }

        h0 = add(a, h0);
        h1 = add(b, h1);
        h2 = add(c, h2);
        h3 = add(d, h3);
        h4 = add(e, h4);
        h5 = add(f, h5);
        h6 = add(g, h6);
        h7 = add(h, h7);
    }

    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
    outputStream.write(h0.toByteArray());
    outputStream.write(h1.toByteArray());
    outputStream.write(h2.toByteArray());
    outputStream.write(h3.toByteArray());
    outputStream.write(h4.toByteArray());
    outputStream.write(h5.toByteArray());
    outputStream.write(h6.toByteArray());
    outputStream.write(h7.toByteArray());
    digest = outputStream.toByteArray();
}

public byte[] getDigest() {
    return digest;
}

private BigInteger add(BigInteger x, BigInteger y) { //Addition modulo 2^32
    return x.add(y).mod(modulo);
}

private BigInteger rotateRight(BigInteger x, int n) {
    return x.shiftRight(n).or(x.shiftLeft(word_size-n));
}

private BigInteger ch(BigInteger x, BigInteger y, BigInteger z) {
    return x.and(y).xor(x.not().and(z));
}

private BigInteger maj(BigInteger x, BigInteger y, BigInteger z) {
    return x.and(y).xor(x.and(z)).xor(y.and(z));
}

private BigInteger sigma0(BigInteger x) {
    return rotateRight(x, 2).xor(rotateRight(x, 13)).xor(rotateRight(x, 22));
}

private BigInteger sigma1(BigInteger x) {
    return rotateRight(x, 6).xor(rotateRight(x, 11)).xor(rotateRight(x, 25));
}

private BigInteger l_sigma0(BigInteger x) {
    return rotateRight(x, 7).xor(rotateRight(x, 18)).xor(x.shiftRight(3));
}

private BigInteger l_sigma1(BigInteger x) {
    return rotateRight(x, 17).xor(rotateRight(x, 19)).xor(x.shiftRight(10));
}
}

0 个答案:

没有答案