diff --git a/test-apps/daily-notification-test/TODO_NATIVE_FETCHER.md b/test-apps/daily-notification-test/TODO_NATIVE_FETCHER.md index a316f0e..aa8cd51 100644 --- a/test-apps/daily-notification-test/TODO_NATIVE_FETCHER.md +++ b/test-apps/daily-notification-test/TODO_NATIVE_FETCHER.md @@ -34,15 +34,45 @@ ## 🔴 High Priority -### 1. ⚠️ VERIFY: Determine Correct JWT Signing Algorithm (CRITICAL) - -- [x] **Status**: ✅ **INVESTIGATION COMPLETE** - See `INVESTIGATION_JWT_ALGORITHM_RESULTS.md` - -**CRITICAL FINDING**: Endorser-ch API expects **DID-based JWTs (ES256K)**, NOT HMAC-SHA256. Current implementation is WRONG and must be replaced. - -**Current State**: Uses SHA-256 hash with `jwtSecret:unsignedToken` format, header claims `"alg": "HS256"` - -**Location**: `TestNativeFetcher.java` → `generateJWTToken()` +### 1. ⚠️ JWT Generation and Verification Status + +- [x] **JWT Generation**: ✅ **COMPLETE** - TypeScript generates ES256K signed JWTs correctly +- [ ] **JWT Verification**: 🟡 **PARTIAL** - Generation works, but server verification fails + +**Current Status** (2025-10-31): + +**✅ JWT Generation (TypeScript)**: +- Using `did-jwt` library with ES256K algorithm ✓ +- Signing with Ethereum private key from seed phrase ✓ +- Correct payload structure (`iat`, `exp`, `iss`, `sub`, `aud`) ✓ +- Location: `test-user-zero.ts` → `generateEndorserJWT()` + +**🟡 JWT Verification Issue**: +- Error: `JWT failed verification: Error: invalid_signature: no matching public key found` +- **Root Cause**: Server cannot resolve DID to get public key for signature verification +- Server uses: `didJwt.verifyJWT(jwt, {resolver})` which requires DID resolution +- The JWT signature is cryptographically valid, but server can't verify it + +**Problem**: DID `did:ethr:0x0000694B58C2cC69658993A90D3840C560f2F51F` may not be: +1. Registered on the resolver/blockchain that the server uses +2. Accessible by the server's DID resolver +3. Configured correctly in the test API server + +**Next Steps** (to be verified): +- [ ] Verify DID registration: Ensure User Zero's DID is registered on resolver server uses +- [ ] Test with known DID: Try a DID that definitely exists in server's system +- [ ] Check server resolver config: Verify server's DID resolver can resolve `did:ethr:` DIDs +- [ ] Check test API server: If using `localhost:3000`, confirm it supports DID-based JWT verification + +**Verification Status Table**: + +| Component | Status | Notes | +|-----------|--------|-------| +| JWT Algorithm | ✅ Correct | ES256K (matches server expectation) | +| JWT Format | ✅ Correct | Proper structure and claims | +| JWT Signature | ✅ Valid | Signature is cryptographically valid | +| DID Resolution | ❌ Failing | Server can't resolve DID to public key | +| Overall Status | 🟡 Partial | Generation works; verification fails due to DID resolution | **Investigation Results** (See `INVESTIGATION_JWT_ALGORITHM_RESULTS.md` for full details): @@ -58,46 +88,35 @@ - Verifies signature using DID resolver (resolves DID to public key) - **NO shared secret used** - authentication is DID-based -**Current Implementation Problem**: -- Currently uses HMAC-SHA256 with shared secret (`jwtSecret`) -- Server will **reject** these tokens as invalid -- Must be replaced with DID-based ES256K signing +**✅ IMPLEMENTATION COMPLETE**: +- TypeScript generates ES256K signed JWTs using `generateEndorserJWT()` +- Native fetcher receives pre-generated JWT token via `configureNativeFetcher()` +- No Java DID library needed - token generated in TypeScript with `did-jwt` library -**Required Implementation Changes:** +**Current Architecture**: +1. TypeScript: `generateEndorserJWT()` → Creates ES256K signed JWT +2. TypeScript: `DailyNotification.configureNativeFetcher({ jwtToken })` → Passes token to native +3. Android: `TestNativeFetcher.configure()` → Stores JWT token +4. Android: Background worker uses stored JWT token for API requests -1. **Remove HMAC-SHA256 implementation** - Completely incorrect approach -2. **Remove `jwtSecret` parameter** - No longer needed (shared secret not used) -3. **Implement DID-based ES256K signing** - Sign with Ethereum private key -4. **Add DID private key retrieval** - Need mechanism to get private key for `activeDid` -5. **Use Java DID library** - did-jwt-java or web3j for ES256K signing +**Remaining Issue**: DID resolution on server side (see verification status above) -**Implementation Options:** +**Previous Implementation (REMOVED)**: +- ~~HMAC-SHA256 with shared secret~~ → Replaced with ES256K DID-based +- ~~Java DID library implementation~~ → Not needed (TypeScript generates token) -**Option 1: Use did-jwt-java Library (Recommended)** -```java -// Add dependency to build.gradle -implementation 'io.uport:uport-did-jwt:3.1.0' // or equivalent +**Implementation Options (NO LONGER NEEDED - TypeScript handles it)**: -// Sign with DID private key -import io.uport.sdk.did.jwt.DIDJWT; -import io.uport.sdk.did.jwt.SimpleSigner; - -String privateKeyHex = getPrivateKeyForDid(activeDid); // Need to implement -SimpleSigner signer = new SimpleSigner(privateKeyHex); -String jwt = DIDJWT.createJWT(payload, signer, issuer: activeDid); +~~**Option 1: Use did-jwt-java Library (Recommended)**~~ +```java +// DEPRECATED - TypeScript generates JWT now +// No longer needed in Java code ``` -**Option 2: Use web3j for Ethereum Signing** +~~**Option 2: Use web3j for Ethereum Signing**~~ ```java -// Add dependency -implementation 'org.web3j:core:4.9.8' - -import org.web3j.crypto.ECKeyPair; -import org.web3j.crypto.Sign; - -ECKeyPair keyPair = getKeyPairForDid(activeDid); // Need to implement -Sign.SignatureData signature = Sign.signMessage( - unsignedToken.getBytes(StandardCharsets.UTF_8), +// DEPRECATED - TypeScript generates JWT now +// No longer needed in Java code keyPair ); // Then encode signature according to ES256K format for JWT