Class HashedCaptchaStore

java.lang.Object
cloud.opencode.base.captcha.store.HashedCaptchaStore
All Implemented Interfaces:
CaptchaStore

public final class HashedCaptchaStore extends Object implements CaptchaStore
Hashed Captcha Store - Decorator that hashes answers before storage 哈希验证码存储 - 在存储前对答案进行哈希处理的装饰器

This decorator wraps any CaptchaStore to hash answers using SHA-256 with a random salt before storing them. Even if the underlying storage is compromised, the plaintext answers cannot be recovered.

此装饰器包装任意 CaptchaStore,在存储前使用 SHA-256 加随机盐对答案进行哈希。 即使底层存储被泄露,也无法恢复明文答案。

Features | 主要功能:

  • Transparent hashing of answers on store - 存储时透明地对答案进行哈希
  • Per-answer random salt generation - 每个答案使用随机盐
  • Timing-safe verification via CaptchaSecurity - 通过 CaptchaSecurity 进行时间安全的验证
  • Atomic verify-and-remove for one-time validation - 原子验证并删除用于一次性验证

Usage Examples | 使用示例:

CaptchaStore delegate = CaptchaStore.memory();
HashedCaptchaStore store = HashedCaptchaStore.wrap(delegate);
store.store("id", "answer", Duration.ofMinutes(5));
boolean valid = store.verifyAnswer("id", "answer");       // true
boolean removed = store.verifyAndRemove("id", "answer");  // true, entry removed

Performance | 性能特性:

  • Store: O(1) + SHA-256 hash - 存储: O(1) + SHA-256 哈希
  • Verify: O(1) + SHA-256 hash + constant-time compare - 验证: O(1) + SHA-256 哈希 + 常量时间比较

Security | 安全性:

  • Thread-safe: Depends on delegate - 线程安全: 取决于委托实现
  • Null-safe: No (parameters must be non-null) - 空值安全: 否(参数不能为空)
Since:
JDK 25, opencode-base-captcha V1.0.3
Author:
Leon Soo www.LeonSoo.com
See Also:
  • Method Details

    • wrap

      public static HashedCaptchaStore wrap(CaptchaStore delegate)
      Wraps a CaptchaStore with hashing (case-insensitive). 使用哈希包装 CaptchaStore(不区分大小写)。
      Parameters:
      delegate - the store to wrap | 要包装的存储
      Returns:
      the hashed store | 哈希存储
      Throws:
      NullPointerException - if delegate is null | 如果委托为 null
    • wrap

      public static HashedCaptchaStore wrap(CaptchaStore delegate, boolean caseSensitive)
      Wraps a CaptchaStore with hashing and configurable case sensitivity. 使用哈希包装 CaptchaStore,可配置大小写敏感。
      Parameters:
      delegate - the store to wrap | 要包装的存储
      caseSensitive - whether answer comparison is case-sensitive | 答案比较是否区分大小写
      Returns:
      the hashed store | 哈希存储
      Throws:
      NullPointerException - if delegate is null | 如果委托为 null
    • store

      public void store(String id, String answer, Duration ttl)
      Stores a CAPTCHA answer after hashing it with a random salt. 使用随机盐对验证码答案进行哈希后存储。

      The stored value is salt:hash so that verification can recover the salt. The plaintext answer is never persisted.

      存储的值为 salt:hash,以便验证时恢复盐。明文答案永远不会被持久化。

      Specified by:
      store in interface CaptchaStore
      Parameters:
      id - the CAPTCHA ID | 验证码 ID
      answer - the plaintext answer | 明文答案
      ttl - the time to live | 存活时间
    • get

      public Optional<String> get(String id)
      Retrieves the stored hash for a CAPTCHA. 检索验证码的存储哈希。

      Returns the raw salt:hash value. For answer verification, use verifyAnswer(String, String) instead.

      返回原始 salt:hash 值。要验证答案,请使用 verifyAnswer(String, String)

      Specified by:
      get in interface CaptchaStore
      Parameters:
      id - the CAPTCHA ID | 验证码 ID
      Returns:
      the stored hash if present | 存储的哈希(如果存在)
    • getAndRemove

      public Optional<String> getAndRemove(String id)
      Retrieves and removes the stored hash for a CAPTCHA. 检索并删除验证码的存储哈希。
      Specified by:
      getAndRemove in interface CaptchaStore
      Parameters:
      id - the CAPTCHA ID | 验证码 ID
      Returns:
      the stored hash if present | 存储的哈希(如果存在)
    • verifyAnswer

      public boolean verifyAnswer(String id, String plainAnswer)
      Verifies a plaintext answer against the stored hash without removing the entry. 验证明文答案与存储的哈希是否匹配,不删除条目。
      Parameters:
      id - the CAPTCHA ID | 验证码 ID
      plainAnswer - the plaintext answer to verify | 要验证的明文答案
      Returns:
      true if the answer matches | 如果答案匹配返回 true
    • verifyAndRemove

      public boolean verifyAndRemove(String id, String plainAnswer)
      Verifies a plaintext answer against the stored hash and removes the entry atomically. 验证明文答案与存储的哈希是否匹配并原子地删除条目。

      This is the recommended method for one-time CAPTCHA validation: the entry is consumed regardless of whether the answer is correct, preventing replay attacks.

      这是一次性验证码验证的推荐方法:无论答案是否正确,条目都会被消耗,防止重放攻击。

      Parameters:
      id - the CAPTCHA ID | 验证码 ID
      plainAnswer - the plaintext answer to verify | 要验证的明文答案
      Returns:
      true if the answer matches | 如果答案匹配返回 true
    • verifyAndRemoveResult

      public ValidationResult verifyAndRemoveResult(String id, String plainAnswer)
      Verifies a plaintext answer and removes the entry, returning a detailed result. 验证明文答案并删除条目,返回详细结果。

      This method performs a single store lookup to distinguish between NOT_FOUND (entry does not exist) and MISMATCH (entry exists but answer is wrong), avoiding the overhead of separate exists() + verifyAndRemove() calls.

      此方法执行单次存储查找以区分 NOT_FOUND(条目不存在)和 MISMATCH(条目存在但答案错误), 避免了分别调用 exists() + verifyAndRemove() 的开销。

      Parameters:
      id - the CAPTCHA ID | 验证码 ID
      plainAnswer - the plaintext answer to verify | 要验证的明文答案
      Returns:
      the validation result | 验证结果
    • remove

      public void remove(String id)
      Description copied from interface: CaptchaStore
      Removes a CAPTCHA. 删除验证码。
      Specified by:
      remove in interface CaptchaStore
      Parameters:
      id - the CAPTCHA ID | 验证码 ID
    • exists

      public boolean exists(String id)
      Description copied from interface: CaptchaStore
      Checks if a CAPTCHA exists. 检查验证码是否存在。
      Specified by:
      exists in interface CaptchaStore
      Parameters:
      id - the CAPTCHA ID | 验证码 ID
      Returns:
      true if exists | 如果存在返回 true
    • clearExpired

      public void clearExpired()
      Description copied from interface: CaptchaStore
      Clears all expired CAPTCHAs. 清除所有过期的验证码。
      Specified by:
      clearExpired in interface CaptchaStore
    • clearAll

      public void clearAll()
      Description copied from interface: CaptchaStore
      Clears all CAPTCHAs. 清除所有验证码。
      Specified by:
      clearAll in interface CaptchaStore
    • size

      public int size()
      Description copied from interface: CaptchaStore
      Gets the current size. 获取当前大小。
      Specified by:
      size in interface CaptchaStore
      Returns:
      the size | 大小