2016-11-03 2 views
1

Может ли кто-нибудь сказать мне, почему следующий код не всегда возвращает тот же хеш? AFAIK единственным способом хэша может отличаться из-за случайную соль, но в соответствии с документацией, я отключение соли, установив размер соли до 0.sha-256 без соли не всегда возвращает тот же самый хэш

public static void main(String[] args) { 
    char[] password = "test_pass".toCharArray(); 
    String str = encodePassword(password); 

    System.out.printf(
     "Byte digest '%s'\n", 
     String.valueOf(Hex.encodeHex(Base64.decodeBase64(str))) 
    ); 
} 

static StandardByteDigester digester = new StandardByteDigester(); 
{ 
    digester.setAlgorithm("SHA-256"); 
    digester.setIterations(100000); 
    digester.setSaltSizeBytes(0); 
    digester.initialize(); 
} 

public static String encodePassword(char[] rawPass) { 
    return new String(Base64.encodeBase64(digester.digest(toBytes(rawPass)))); 
} 

public static byte[] toBytes(char[] ch) { 
    Charset charset = Charset.defaultCharset(); 
    ByteBuffer buff = charset.encode(CharBuffer.wrap(ch)); 
    byte[] tmp = new byte[buff.limit()]; 
    buff.get(tmp); 
    return tmp;  
} 
+0

какая версия jasypt вы используете? – Asoub

ответ

3

Вашей ошибка связана с тем, что вы инициализировать статическое поле StandardByteDigester digester в инициализаторе блоке экземпляра вместо статического инициализатора блока таким образом, что он никогда не вызываются, как вы никогда не создать экземпляр вашего класса так в конце он использует конфигурацию по умолчанию со случайной солью.

Попробуйте это:

static { 
    digester.setAlgorithm("SHA-256"); 
    digester.setIterations(100000); 
    digester.setSaltSizeBytes(0); 
    digester.initialize(); 
} 

Ваш код может быть упрощен, если ваш метод encodePassword взял String вместо char массива, как вы могли бы просто назвать getBytes(Charset) в следующем:

public static String encodePassword(String rawPass) { 
    return new String(
     Base64.encodeBase64(digester.digest(rawPass.getBytes(StandardCharsets.UTF_8))), 
     StandardCharsets.US_ASCII 
    ); 
} 

NB: Неправильная практика полагаться на кодировку по умолчанию для платформы, так как ваш код будет тогда зависимым от платформы, поэтому здесь, поскольку все 64 символа все включены в US_ASCII, давайте использовать эту кодировку для декодирования.

+1

Спасибо, это действительно решило :) – user2817219

Смежные вопросы