public class ConsolePasswordManagerextends RouterPasswordManager
Manage both plaintext and salted/hashed password storage in router.config.
  • Field Details

    • PROP_MIGRATED

      private static final String PROP_MIGRATED
      Property marking the password migration as done.
      See Also:
    • PROP_CONSOLE_OLD

      private static final String PROP_CONSOLE_OLD
      Old plaintext console password property, migrated to a hash.
      See Also:
    • CONSOLE_USER

      private static final String CONSOLE_USER
      User name the console password is stored under.
      See Also:
    • PROP_PBKDF2

      private static final String PROP_PBKDF2
      Suffix of the hashed password property.
      See Also:
    • PBKDF2_ITERATIONS

      private static final int PBKDF2_ITERATIONS
      PBKDF2 rounds used when hashing a password.
      See Also:
    • COLON_SPLIT

      private static final Pattern COLON_SPLIT
      Splits a stored hash into its parts.
    • _random

      private static final SecureRandom _random
      Generates password salts.
  • Constructor Details

    • ConsolePasswordManager

      public ConsolePasswordManager(RouterContext ctx)
      Create a manager over the router's config store, migrating any legacy plaintext "consolePassword" entry to the salted/hash form on the way in.
      Parameters:
      ctx - the router context whose config store holds the passwords
  • Method Details

    • checkMD5

      public boolean checkMD5(String realm, String subrealm, String user, String pw)
      Straight MD5. Compatible with Jetty.
      Parameters:
      realm - e.g. i2cp, routerconsole, etc.
      subrealm - the HTTP digest subrealm, hashed between the user and the password
      user - null or "" for no user, already trimmed
      pw - plain text, already trimmed
      Returns:
      if pw verified
    • checkPBKDF2

      private boolean checkPBKDF2(String realm, String user, String pw)
      PBKDF2 hash for password storage. Backward compatible - checks PBKDF2 first, falls back to MD5.
      Parameters:
      realm - e.g. i2cp, routerconsole, etc.
      user - null or "" for no user, already trimmed
      pw - plain text, already trimmed
      Returns:
      if pw verified
    • HexDecode

      static byte[] HexDecode(String hex)
      Decode a fixed-width hex string into exactly hex.length()/2 bytes.

      DELIBERATE DEVIATION from the DataHelper canonical-source rule: DataHelper.fromHexString(String) decodes via BigInteger and returns the minimum-length, sign-aware representation - a leading '0' nibble is stripped and a first nibble of 8-f gains an extra 0x00 byte. Password salts and hashes must round-trip at their exact stored width; using fromHexString here corrupted ~15/16 of PBKDF2 credentials and locked users out of the console.

      Parameters:
      hex - even-length hex string, either case, no prefix
      Returns:
      decoded bytes, always exactly hex.length()/2 long
      Throws:
      IllegalArgumentException - on odd length or non-hex character
    • getMD5

      public Map<String,String> getMD5(String realm)
      Get all MD5 usernames and passwords. Compatible with Jetty. Any "null" user is NOT included..
      Parameters:
      realm - e.g. i2cp, routerconsole, etc.
      Returns:
      Map of usernames to passwords (hex with leading zeros, 32 characters)
    • getPBKDF2

      public Map<String,String> getPBKDF2(String realm)
      Get all users with PBKDF2 passwords.
      Parameters:
      realm - e.g. routerconsole.auth.i2prouter
      Returns:
      Map of usernames to PBKDF2 hashes
    • migrateConsole

      private boolean migrateConsole()
      Migrate from plaintext to MD5 hash Ref: RFC 2617.
      Returns:
      success or nothing to migrate
    • saveMD5

      public boolean saveMD5(String realm, String subrealm, String user, String pw)
      Straight MD5, no salt Compatible with Jetty and RFC 2617.

      Upgrades to PBKDF2 on save (subrealm is unused for PBKDF2).

      Parameters:
      realm - The full realm, e.g. routerconsole.auth.i2prouter, etc.
      subrealm - unused (for backward compatibility)
      user - non-null, non-empty, already trimmed
      pw - the plain text password to hash
      Returns:
      true if the PBKDF2 entry reached router.config; false if the JCE provider rejects PBKDF2 or the key spec
    • savePBKDF2

      private boolean savePBKDF2(String realm, String subrealm, String user, String pw)
      Save password as PBKDF2 hash. Backward compatible - saves new PBKDF2, keeps old MD5 for migration.
      Parameters:
      realm - The full realm
      subrealm - unused for PBKDF2
      user - non-null, non-empty
      pw - the plain text password to hash
      Returns:
      true if the PBKDF2 entry reached router.config; false if the JCE provider rejects PBKDF2 or the key spec
    • HexEncode

      static String HexEncode(byte[] data)
      Encode a byte array to a lowercase hex string. Two hex characters per byte with leading zeros.
      Parameters:
      data - the byte array to encode
      Returns:
      lowercase hex string