diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/housekeeping/HousekeepingResetUserPasswordEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/housekeeping/HousekeepingResetUserPasswordEvent.java index 1f1a57ba..14142002 100644 --- a/Emulator/src/main/java/com/eu/habbo/messages/incoming/housekeeping/HousekeepingResetUserPasswordEvent.java +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/housekeeping/HousekeepingResetUserPasswordEvent.java @@ -4,10 +4,8 @@ import com.eu.habbo.Emulator; import com.eu.habbo.habbohotel.permissions.Permission; import com.eu.habbo.messages.incoming.MessageHandler; import com.eu.habbo.messages.outgoing.housekeeping.HousekeepingActionResultComposer; +import org.mindrot.jbcrypt.BCrypt; -import java.nio.charset.StandardCharsets; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.sql.Connection; import java.sql.PreparedStatement; @@ -15,19 +13,18 @@ import java.sql.SQLException; /** * Reset a user's password to a fresh random 12-character alphanumeric - * string. Persists the SHA-256 hex of the new password into - * `users.password` (varchar(64) — sized to hold SHA-256 hex), clears - * `auth_ticket` so any active session can't be re-used to bypass the - * reset, and ships the PLAINTEXT new password back to the operator in - * the action-result `message` so they can communicate it out-of-band. - * - * If your CMS uses a hash other than SHA-256 (bcrypt / argon2 / SHA-1), - * swap the MessageDigest constant — the rest of the flow is hash-agnostic. + * string. Persists a BCrypt `$2a$` hash of the new password into + * `users.password` (matches what `AuthHttpUtil.checkPassword` / + * `SessionEndpoints` / `AccountChangeEndpoints` already write and read), + * clears `auth_ticket` so any active session can't be re-used to bypass + * the reset, and ships the PLAINTEXT new password back to the operator + * in the action-result `message` so they can communicate it out-of-band. */ public class HousekeepingResetUserPasswordEvent extends MessageHandler { private static final String ACTION_KEY = "user.reset_password"; private static final String PASSWORD_ALPHABET = "ABCDEFGHJKLMNPQRSTUVWXYZabcdefghjkmnpqrstuvwxyz23456789"; private static final int PASSWORD_LENGTH = 12; + private static final int BCRYPT_COST = 10; private static final SecureRandom RNG = new SecureRandom(); @@ -53,8 +50,8 @@ public class HousekeepingResetUserPasswordEvent extends MessageHandler { String hash; try { - hash = sha256Hex(plain); - } catch (NoSuchAlgorithmException e) { + hash = BCrypt.hashpw(plain, BCrypt.gensalt(BCRYPT_COST)); + } catch (IllegalArgumentException e) { this.client.sendResponse(new HousekeepingActionResultComposer(ACTION_KEY, false, 0, "housekeeping.error.hash_failed")); return; } @@ -89,16 +86,4 @@ public class HousekeepingResetUserPasswordEvent extends MessageHandler { return sb.toString(); } - - private static String sha256Hex(String plain) throws NoSuchAlgorithmException { - MessageDigest md = MessageDigest.getInstance("SHA-256"); - byte[] digest = md.digest(plain.getBytes(StandardCharsets.UTF_8)); - StringBuilder hex = new StringBuilder(digest.length * 2); - - for (byte b : digest) { - hex.append(String.format("%02x", b)); - } - - return hex.toString(); - } }