Мне нужно изменить платформы сайта с 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-код.