Domanda

Im using the following method to generate pass phrases for aes encryption.

MY aes needs 16 bytes for a key.

Here is how I am getting my key

    public  byte[] sha256digest16(String[] list) throws NoSuchAlgorithmException, UnsupportedEncodingException {
        MessageDigest digest = MessageDigest.getInstance("SHA-256");
        digest.reset();
        for(String s: list){
            digest.update(s.getBytes("UTF-8"));
        }
        byte[]  b = digest.digest();

        return String.format("%0" + (b.length) + 'x', new BigInteger(1, b)).getBytes("UTF-8");

    }

However, it is 64 bytes. How I can I get this method to return a 16 byte string

EDIT The main reason Im doing this is because my python code is

from Crypto.Hash import SHA256


myHash = SHA256.new()
myHash.update("265jMeges")
print myHash.hexdigest()

which outputs

917ef7e7be4a84e279b74a257953307f1cff4a2e3d221e363ead528c6b556edb

where is the java output of is

efbfbd7eefbfbdefbfbd4aefbfbdefbfbd79efbfbd4a257953307f1cefbfbd4a2e3d221e363eefbfbd52efbfbd6b556eefbfbd

for the same string. Why are they different?

È stato utile?

Soluzione

SHA-256 returns 32 bytes by default (256 / 8 = 32), not 16. The normal way to use a part of a hash is to use the first (leftmost) 16 bytes of the resulting hash. You can do this by applying the Java copyOf method on the result of SHA-256.

Please use a real hexadecimal encoder to display the result (not to return a value, you don't need any String instances at all). Using BigInteger is error prone and may add or remove bytes.

Try for instance:

public static byte[] sha256digest16(String[] list) throws NoSuchAlgorithmException, UnsupportedEncodingException {
    MessageDigest digest = MessageDigest.getInstance("SHA-256");
    digest.reset();
    for(String s: list){
        digest.update(s.getBytes("UTF-8"));
    }

    // so you have 32 bytes here
    byte[]  b = digest.digest();

    // you can return it directly or you can cut it to 16 bytes
    return Arrays.copyOf(b, 16);
}

For display as hexadecimals use:

public static String tohex(byte[] data) {
    StringBuilder sb = new StringBuilder(data.length * 2);
    for (int i = 0; i < data.length; i++) {
        sb.append(String.format("%02X", data[i] & 0xFF));
    }
    return sb.toString();
}

Or use one of the hex encoders of the Apache commons codec, Bouncy Castle or Guava.

Altri suggerimenti

You're formatting the result bytes as hex, which multiplies the bit occupancy by a factor of 2. You'll never get 16 bytes that way. Get rid of the String.format() line and just return the result of the digest() method. I expect you're repeating the process elsewhere which is doubling it again,

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top