Class HashedCaptchaStore
- All Implemented Interfaces:
CaptchaStore
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 Summary
Modifier and TypeMethodDescriptionvoidclearAll()Clears all CAPTCHAs.voidClears all expired CAPTCHAs.booleanChecks if a CAPTCHA exists.Retrieves the stored hash for a CAPTCHA.getAndRemove(String id) Retrieves and removes the stored hash for a CAPTCHA.voidRemoves a CAPTCHA.intsize()Gets the current size.voidStores a CAPTCHA answer after hashing it with a random salt.booleanverifyAndRemove(String id, String plainAnswer) Verifies a plaintext answer against the stored hash and removes the entry atomically.verifyAndRemoveResult(String id, String plainAnswer) Verifies a plaintext answer and removes the entry, returning a detailed result.booleanverifyAnswer(String id, String plainAnswer) Verifies a plaintext answer against the stored hash without removing the entry.static HashedCaptchaStorewrap(CaptchaStore delegate) Wraps aCaptchaStorewith hashing (case-insensitive).static HashedCaptchaStorewrap(CaptchaStore delegate, boolean caseSensitive) Wraps aCaptchaStorewith hashing and configurable case sensitivity.
-
Method Details
-
wrap
Wraps aCaptchaStorewith hashing (case-insensitive). 使用哈希包装CaptchaStore(不区分大小写)。- Parameters:
delegate- the store to wrap | 要包装的存储- Returns:
- the hashed store | 哈希存储
- Throws:
NullPointerException- if delegate is null | 如果委托为 null
-
wrap
Wraps aCaptchaStorewith 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
Stores a CAPTCHA answer after hashing it with a random salt. 使用随机盐对验证码答案进行哈希后存储。The stored value is
salt:hashso that verification can recover the salt. The plaintext answer is never persisted.存储的值为
salt:hash,以便验证时恢复盐。明文答案永远不会被持久化。- Specified by:
storein interfaceCaptchaStore- Parameters:
id- the CAPTCHA ID | 验证码 IDanswer- the plaintext answer | 明文答案ttl- the time to live | 存活时间
-
get
Retrieves the stored hash for a CAPTCHA. 检索验证码的存储哈希。Returns the raw
salt:hashvalue. For answer verification, useverifyAnswer(String, String)instead.返回原始
salt:hash值。要验证答案,请使用verifyAnswer(String, String)。- Specified by:
getin interfaceCaptchaStore- Parameters:
id- the CAPTCHA ID | 验证码 ID- Returns:
- the stored hash if present | 存储的哈希(如果存在)
-
getAndRemove
Retrieves and removes the stored hash for a CAPTCHA. 检索并删除验证码的存储哈希。- Specified by:
getAndRemovein interfaceCaptchaStore- Parameters:
id- the CAPTCHA ID | 验证码 ID- Returns:
- the stored hash if present | 存储的哈希(如果存在)
-
verifyAnswer
Verifies a plaintext answer against the stored hash without removing the entry. 验证明文答案与存储的哈希是否匹配,不删除条目。- Parameters:
id- the CAPTCHA ID | 验证码 IDplainAnswer- the plaintext answer to verify | 要验证的明文答案- Returns:
- true if the answer matches | 如果答案匹配返回 true
-
verifyAndRemove
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 | 验证码 IDplainAnswer- the plaintext answer to verify | 要验证的明文答案- Returns:
- true if the answer matches | 如果答案匹配返回 true
-
verifyAndRemoveResult
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 | 验证码 IDplainAnswer- the plaintext answer to verify | 要验证的明文答案- Returns:
- the validation result | 验证结果
-
remove
Description copied from interface:CaptchaStoreRemoves a CAPTCHA. 删除验证码。- Specified by:
removein interfaceCaptchaStore- Parameters:
id- the CAPTCHA ID | 验证码 ID
-
exists
Description copied from interface:CaptchaStoreChecks if a CAPTCHA exists. 检查验证码是否存在。- Specified by:
existsin interfaceCaptchaStore- Parameters:
id- the CAPTCHA ID | 验证码 ID- Returns:
- true if exists | 如果存在返回 true
-
clearExpired
public void clearExpired()Description copied from interface:CaptchaStoreClears all expired CAPTCHAs. 清除所有过期的验证码。- Specified by:
clearExpiredin interfaceCaptchaStore
-
clearAll
public void clearAll()Description copied from interface:CaptchaStoreClears all CAPTCHAs. 清除所有验证码。- Specified by:
clearAllin interfaceCaptchaStore
-
size
public int size()Description copied from interface:CaptchaStoreGets the current size. 获取当前大小。- Specified by:
sizein interfaceCaptchaStore- Returns:
- the size | 大小
-