Intereting Posts

Можете ли вы получить тот же Java SHA-1 в PHP, пожалуйста?

Мне нужно изменить платформы сайта с Java на PHP, но я хотел бы сохранить все пароли моего пользователя …

У меня был этот код для хэширования паролей, прежде чем написание хешированного значения в качестве пароля для веб-сайта:

MessageDigest md = null; md = MessageDigest.getInstance("SHA"); md.update(plaintext.getBytes("UTF-8")); byte raw[] = md.digest(); hash = new Base64().encodeToString(raw).replaceAll("\n", "").replaceAll("\r", ""); 

Я думаю, что код Java сделал SHA-1 хэширование пароля, но только до того, как он был закодирован в UTF-8, а затем был закодирован Base64.

Я хотел бы, чтобы PHP-код делал то же самое, т. Е. Возвращал одно и то же значение хэша для того же пароля, что и в Java, только кажется, что PHP-код, делающий SHA-1-хеширование, у меня не будет возвращать тот же SHA (-1, а не Base64 закодировано, я думаю?) Значение по сравнению с декодированным значением Java Base64 хэша … может ли это иметь отношение к тому, что мои пароли в PHP не кодируются сначала байтом UTF-8 ( и как я могу это сделать в PHP), пожалуйста?

п.с.

Еще одна странная вещь … мои пароли в Java – это все 28 символов (обычно что-то вроде этого rnwn4zTNgH30l4pP8V05lRVGmF4= ) … но значение Base64().decode(hash) этих хэшей паролей имеет длину 10 символов (пример [B@14e1f2b ).

Я думал, что Base64 сделал дополнительный 1 символ для каждого 3 чартера (28 или 27, исключая прописку = чартер, намного больше, чем третья больше, чем эти 10 символов), так что я делаю декодирование неправильно?

И вдобавок ко всему, что хэшированные значения пароля SHA-1 в PHP составляют 40 символов (в базе данных mysql UTF-8), например dd94709528bb1c83d08f3088d4043f4742891f4f ?

[B@14e1f2b определенно не хэш. Это результат неявного преобразования из byte[] в String .

Похоже, вы делаете что-то вроде этого:

 String decodedHash = Base64().decode(hash); // Produces [B@14e1f2b 

Однако правильное представление хэша представляет собой массив байтов:

 byte[] decodedHash = Base64().decode(hash); 

То, что я обычно делаю с Java для вычисления хэша SHA-1, который точно идентичен функции PHP sha1 (), является следующим. Ключ в том, что toHexString используется для отображения необработанных байтов печатным способом. Если вы используете функцию PHP и хотите получить тот же результат своего запутанного процесса, вам нужно использовать параметр $ raw_output для true в PHP, чтобы получить необработанные байты и применить Base64. Полный исходный код .

 /** * Compute a SHA-1 hash of a String argument * * @param arg the UTF-8 String to encode * @return the sha1 hash as a string. */ public static String computeSha1OfString(String arg) { try { return computeSha1OfByteArray(arg.getBytes(("UTF-8"))); } catch (UnsupportedEncodingException ex) { throw new UnsupportedOperationException(ex); } } private static String computeSha1OfByteArray(byte[] arg) { try { MessageDigest md = MessageDigest.getInstance("SHA-1"); md.update(arg); byte[] res = md.digest(); return toHexString(res); } catch (NoSuchAlgorithmException ex) { throw new UnsupportedOperationException(ex); } } private static String toHexString(byte[] v) { StringBuilder sb = new StringBuilder(v.length * 2); for (int i = 0; i < v.length; i++) { int b = v[i] & 0xFF; sb.append(HEX_DIGITS.charAt(b >>> 4)).append(HEX_DIGITS.charAt(b & 0xF)); } return sb.toString(); } 

Sha1 () PHP каждый кодирует каждый байт вывода как шестнадцатеричный по умолчанию, но вы можете получить исходный вывод, передав true в качестве второго аргумента:

 $digest = sha1($password, true); // This returns the same string of bytes as md.digest() 

Затем передайте дайджест на base64_encode, и вы закончите:

 base64_encode(sha1($password, true)); 

Это возвращает тот же самый SHA-1 хэш как ваш Java-код.