[ 
https://issues.apache.org/jira/browse/WICKET-7190?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18101688#comment-18101688
 ] 

ASF GitHub Bot commented on WICKET-7190:
----------------------------------------

papegaaij opened a new pull request, #1536:
URL: https://github.com/apache/wicket/pull/1536

   Wicket had three overlapping crypt abstractions — 
`org.apache.wicket.util.crypt.ICrypt` (URL encryption, "remember me"), 
`org.apache.wicket.pageStore.crypt.ICrypter` (page store), and the 
`ICryptFactory` hierarchy — with different guarantees. Notably the page store 
default, `DefaultCrypter`, was AES-256-CBC: unauthenticated, so stored bytes 
were confidential but malleable, and tampered ciphertext still reached the 
deserializer.
   
   This replaces all of it with one authenticated abstraction.
   
   > **Base branch:** this targets `document-security-model` (#1535), not 
`master` — the first commit edits `SECURITY.md`, which that branch introduces. 
It will retarget to `master` automatically once the base merges.
   
   ### What changes
   
   **One interface.** `org.apache.wicket.core.util.crypt.ICrypt` is now the 
single abstraction, used by the page store, `CryptoMapper` and the 
authentication cookie alike. It operates on `byte[]` with an optional 
associated-data parameter, and provides the URL-safe Base64 `String` layer as 
default methods. `decrypt` returns `null` on *any* failure — unknown scheme, 
failed authentication, malformed input — so callers uniformly treat 
undecryptable data as absent rather than catching exceptions.
   
   **Authenticated by default, and self-describing.** `SchemeCrypt` writes 
`marker(1) || scheme-payload`, where the marker is the id of the `ICryptScheme` 
that produced the payload. Encryption always uses the configured scheme; 
decryption looks the marker up in a whitelist and refuses anything not on it. 
The marker is authenticated as associated data, so it cannot be altered to 
force a weaker scheme — together that gives downgrade protection, and a 
documented migration path (whitelist the old scheme while the new one becomes 
the encryption scheme, then drop it once data is rewritten).
   
   **Two shipped schemes**, both AEAD:
   - `AesGcmCryptScheme` — JDK-native AES-256-GCM. The new default; no extra 
dependencies.
   - `AesGcmSivCryptScheme` — AES-256-GCM-SIV, nonce-misuse resistant. Requires 
Bouncy Castle.
   
   **Scheme and key source are separated.** An `ICryptScheme` decides *how* 
data is encrypted and generates the keys it consumes; an `ICryptFactory` 
decides only *where* the key lives — `KeyInSessionCryptFactory` (per session, 
the default) or `ApplicationKeyCryptFactory` (application-wide, for stateless 
deployments).
   
   **Encrypted pages are bound to their page id.** `CryptingPageStore` passes 
the page id as associated data, so a stored page cannot be replayed as a 
different one.
   
   ### Behavioural fix outside the crypt package
   
   `AbstractFileUploadResource` validated its signed upload settings by 
re-encrypting the expected values and comparing the resulting *ciphertext*. 
That only worked because the previous default was deterministic PBE. 
`SchemeCrypt` uses a fresh nonce per message, as an AEAD mode must, so the 
comparison could never succeed and every `FileUploadToResourceField` upload 
would have been rejected. It now decrypts the token and compares the settings 
it carries; the authentication tag is what makes the token unforgeable, and 
`FileUploadToResourceFieldSecurityTest` still rejects tampered limits.
   
   ### Compatibility — this is a Wicket 11 API break
   
   Removed with no replacement: `SunJceCrypt`, `AbstractCrypt`, `TrivialCrypt`, 
`CryptFactoryCachingDecorator`, `AESCrypt`, `AbstractJceCrypt`, 
`KeyInSessionSunJceCryptFactory`, `AbstractKeyInSessionCryptFactory`, 
`DefaultCrypter`, `GCMSIVCrypter`, `ICrypter`. `NoCrypt`, `NoCryptFactory` and 
`ICryptFactory` move to `org.apache.wicket.core.util.crypt`. OpenRewrite 
recipes for the moves and notes on the removals are in `wicket-migration`.
   
   Existing ciphertext does not decrypt under the new schemes. In practice that 
means encrypted URLs and page store entries from a previous version are treated 
as expired, and "remember me" cookies are invalidated.
   
   ### Testing
   
   - Full `wicket-core-tests` suite: **2331 tests, 0 failures**.
   - Full reactor `clean test-compile` passes.
   - New coverage: `SchemeCryptTest` (19), `CryptFactoryTest` (3), plus 
extended `CryptoMapperTest` and `CryptingPageStoreTest` — round-trips, 
associated-data mismatch, whitelist refusal, marker tampering.
   
   **Known red:** `japicmp` will fail on the removals above and needs a Wicket 
11 baseline before CI is green.
   
   🤖 Generated with [Claude Code](https://claude.com/claude-code)
   




> Unified cryptography API
> ------------------------
>
>                 Key: WICKET-7190
>                 URL: https://issues.apache.org/jira/browse/WICKET-7190
>             Project: Wicket
>          Issue Type: New Feature
>          Components: wicket-core
>            Reporter: Emond Papegaaij
>            Assignee: Emond Papegaaij
>            Priority: Major
>             Fix For: 11.0.0
>
>
> The current cryptography API in Wicket is split over {{ICrypt}} and 
> {{ICrypter}}. Both APIs serve a similar purpose but for different subsystems. 
> The goal is to unify these APIs and to allow the implementation of more 
> modern ciphers, with AEAD support. Also, the documentation on this API and 
> its implementations must be improved, clearly stating what it does and what 
> it does not deliver.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to