docs(todo): update JWT verification status and next steps
- Update JWT section to reflect current status: - JWT Generation: ✅ COMPLETE (TypeScript generates ES256K correctly) - JWT Verification: 🟡 PARTIAL (generation works, server verification fails) - Document verification issue: - Error: 'no matching public key found' - Root cause: Server cannot resolve DID to get public key - JWT signature is cryptographically valid - Issue is DID resolution, not JWT generation - Add verification status table: - Component-level status breakdown - Clear distinction between generation (✅) and verification (❌) - Add next steps checklist: - Verify DID registration on resolver - Test with known DID - Check server resolver config - Verify test API server supports DID-based JWT verification - Update implementation status: - Mark TypeScript JWT generation as complete - Mark DID resolution as pending verification - Remove outdated HMAC-SHA256 references
This commit is contained in:
@@ -34,15 +34,45 @@
|
||||
|
||||
## 🔴 High Priority
|
||||
|
||||
### 1. ⚠️ VERIFY: Determine Correct JWT Signing Algorithm (CRITICAL)
|
||||
### 1. ⚠️ JWT Generation and Verification Status
|
||||
|
||||
- [x] **Status**: ✅ **INVESTIGATION COMPLETE** - See `INVESTIGATION_JWT_ALGORITHM_RESULTS.md`
|
||||
- [x] **JWT Generation**: ✅ **COMPLETE** - TypeScript generates ES256K signed JWTs correctly
|
||||
- [ ] **JWT Verification**: 🟡 **PARTIAL** - Generation works, but server verification fails
|
||||
|
||||
**CRITICAL FINDING**: Endorser-ch API expects **DID-based JWTs (ES256K)**, NOT HMAC-SHA256. Current implementation is WRONG and must be replaced.
|
||||
**Current Status** (2025-10-31):
|
||||
|
||||
**Current State**: Uses SHA-256 hash with `jwtSecret:unsignedToken` format, header claims `"alg": "HS256"`
|
||||
**✅ 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()`
|
||||
|
||||
**Location**: `TestNativeFetcher.java` → `generateJWTToken()`
|
||||
**🟡 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)**
|
||||
**Implementation Options (NO LONGER NEEDED - TypeScript handles it)**:
|
||||
|
||||
~~**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
|
||||
|
||||
// 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);
|
||||
// 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
|
||||
|
||||
Reference in New Issue
Block a user