← Back to PRs

#5867: Android: Add BouncyCastle Ed25519 fallback and gateway token UI

by brandonpollack23 open 2026-02-01 02:44 View on GitHub →
app: android
## Summary Fixes Android app connection issues on devices where the system Ed25519 KeyPairGenerator fails with "Not initialized" (observed on Android 16). ## Changes - **BouncyCastle fallback**: Added BouncyCastle dependency and lightweight API fallback for Ed25519 key generation and signing when the system provider fails - **Gateway token UI**: Added a Gateway Token input field in Settings > Advanced section so users can authenticate with token-based gateways ## Details ### Ed25519 Fallback - `DeviceIdentityStore.generate()`: Tries system `KeyPairGenerator.getInstance("Ed25519")` first, falls back to BouncyCastle's `Ed25519KeyPairGenerator` - `DeviceIdentityStore.signPayload()`: Tries system JCA first, falls back to BouncyCastle's `Ed25519Signer` - Handles both PKCS8-encoded keys (from system provider) and raw 32-byte keys (from BouncyCastle) ### Gateway Token UI - Added `gatewayToken` StateFlow and setter through SecurePrefs → NodeRuntime → MainViewModel - Added OutlinedTextField in SettingsSheet under the Advanced section - Token is loaded during connection and used for gateway authentication ## Testing Tested on Android 16 device where system Ed25519 was failing. Connection now succeeds using BouncyCastle fallback and token authentication. <!-- greptile_comment --> <h2>Greptile Overview</h2> <h3>Greptile Summary</h3> This PR adds an Android Ed25519 keygen/signing fallback using BouncyCastle to address devices where the platform `Ed25519` provider fails, and introduces a “Gateway Token” setting surfaced via `SecurePrefs` → `NodeRuntime` → `MainViewModel` and shown in the Settings Advanced section. The crypto changes are localized to `DeviceIdentityStore` (load/create identity, sign payloads) and the UI/settings changes thread a new token value into runtime configuration used during gateway connection. Overall this fits the existing pattern of storing advanced connection settings in `SecurePrefs` and exposing them as `StateFlow`s. Main concern: the fallback signing path assumes a very specific PKCS#8 encoding shape; on devices where the system signer fails but an existing identity was generated earlier by the system provider, BouncyCastle fallback may still fail to sign and return `null`, keeping the connection broken. <h3>Confidence Score: 3/5</h3> - This PR is mostly safe to merge, but has a meaningful risk of still failing on some devices due to PKCS#8 parsing assumptions in the Ed25519 fallback. - The changes are small and targeted, but the BouncyCastle fallback’s handling of existing PKCS#8-encoded keys is brittle; if the system provider fails and the stored key encoding doesn’t match the hard-coded prefix+32 layout, signing will return null and connections can still fail. The new UI/settings wiring looks straightforward with low blast radius. - apps/android/app/src/main/java/ai/openclaw/android/gateway/DeviceIdentityStore.kt <!-- greptile_other_comments_section --> <sub>(2/5) Greptile learns from your feedback when you react with thumbs up/down!</sub> **Context used:** - Context from `dashboard` - CLAUDE.md ([source](https://app.greptile.com/review/custom-context?memory=fd949e91-5c3a-4ab5-90a1-cbe184fd6ce8)) - Context from `dashboard` - AGENTS.md ([source](https://app.greptile.com/review/custom-context?memory=0d0c8278-ef8e-4d6c-ab21-f5527e322f13)) <!-- /greptile_comment -->

Most Similar PRs