KRYSTALM7 opened a new pull request, #130:
URL: https://github.com/apache/fineract-loan-origination/pull/130

   ## Description
   
   Adds RSA-AES hybrid payload encryption for login credentials to 
preventplaintext password exposure in the browser's network tab.
   
   The frontend fetches a fresh RSA-2048 public key from the server before each 
login, encrypts the password client-side using AES-256-GCM, wraps the AES key 
with RSA-OAEP, and sends only the encrypted envelope over the wire. The server 
decrypts using an in-memory private key that is never persisted or logged.
   
   ## Changes
   
   ### Backend
   
   - Added `CryptoKeyController` exposing `GET /api/v1/auth/public-key`  
returning the RSA-2048 public key in SPKI/Base64 format.
   - Added `crypto/` package with in-memory RSA-2048 key pair generation on 
startup — the private key never leaves the JVM heap and is never logged or 
persisted.
   - Updated `AuthController` with encrypted endpoint variants: `POST 
/api/v1/auth/login/encrypted` and `POST /api/v1/auth/staff/login/encrypted`.
   - Updated `FineractAuthenticationProvider` to unwrap the AES key using 
RSA-OAEP and decrypt the AES-GCM payload before credential validation.
   - Updated `RateLimitFilter` to recognise the `/encrypted` endpoint variants 
under the same rate-limiting rules as the plain endpoints.
   - Plain `/login` endpoints remain fully functional for local development.
   
   ### Frontend
   
   - Added `PayloadEncryptionService` using the Web Crypto API:
     - Fetches the server's RSA public key with a cache-busting timestamp to 
always match the backend's current in-memory key pair.
     - Generates a fresh AES-256-GCM key per login attempt.
     - Encrypts the JSON payload with a random 96-bit IV; prepends IV to 
ciphertext.
     - Wraps the AES key with RSA-OAEP SHA-256.
     - Returns `{ wrappedKey, ciphertext }` as Base64 strings.
   - Updated `AuthService` to POST the encrypted envelope to
     `/api/v1/auth/login/encrypted`.
   - Updated `StaffAuthService` to POST the encrypted envelope to
     `/api/v1/auth/staff/login/encrypted`.
   - Updated all affected frontend unit tests to mock
     `PayloadEncryptionService` and assert against the encrypted endpoints.
   
   ## Verification
   
   - Verified plaintext password is no longer visible in the browser network 
tab on login.
   - Verified `GET /api/v1/auth/public-key` returns a valid RSA-2048 public key.
   - Verified encrypted login endpoints correctly decrypt and authenticate.
   - Verified plain `/login` endpoints remain functional.
   - Verified all existing frontend unit tests pass with mocked encryption.
   - Verified no credentials appear in logs or response bodies.
   
   ## Security Context
   
   This complements the existing server-side hardening already in place:
   
   - Argon2id password hashing (BCrypt-compatible fallback)
   - `Cache-Control: no-store` on login responses
   - CSP and security headers (nosniff, Referrer-Policy, Permissions-Policy)
   - HSTS configured for HTTPS deployments
   - Rate limiting on all auth endpoints
   - Credential-related fields removed from response bodies and logs
   
   ## Notes
   
   The protocol uses RSA-OAEP + AES-256-GCM (hybrid encryption) rather than 
RSA-OAEP alone because RSA-OAEP has a maximum plaintext size limited by the key 
length. AES-GCM has no such limit and provides authenticated encryption, 
ensuring both confidentiality and integrity of the payload.
   
   The RSA key pair is regenerated each time the server starts. A client 
holding a stale public key will receive a decryption failure and must retry, 
the cache-busting timestamp on `GET /api/v1/auth/public-key` prevents this in 
practice.
   
   
   Closes #101
   
   ## JIRA
   
   [FINERACT-2442](https://issues.apache.org/jira/browse/FINERACT-2442)


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to