Session Transcript
The session transcript is a cryptographic binding that ties each mDoc presentation to a specific session, preventing replay attacks and ensuring data authenticity.
Purpose
The session transcript serves critical security functions:
- Replay prevention: A response signed in one session cannot be used in another
- Session binding: Ensures the device response was created for this specific interaction
- Integrity verification: Both parties can verify they're in the same session
Transcript Structure
The session transcript is computed from engagement data per ISO 18013-5:
SessionTranscript = [
DeviceEngagementBytes, // CBOR-encoded device engagement
EReaderKeyBytes, // Reader's ephemeral public key (if applicable)
Handover // Additional handover data (QR/NFC/OID4VP specific)
]
How It Works
During Engagement
- The holder creates a device engagement with an ephemeral key
- The verifier receives the engagement and generates its own ephemeral key
- Both parties compute the session transcript from the same inputs
During Response Signing
The holder signs the device response with a signature that covers:
DeviceAuthentication = [
"DeviceAuthentication", // Context string
SessionTranscript, // The computed transcript
DocType, // Document type being presented
DeviceNameSpaceBytes // Additional device-signed data (if any)
]
During Verification
The verifier computes the same transcript and verifies that:
- The device signature is valid
- The signature was computed over the correct transcript
- The transcript matches the verifier's view of the session
Handover Types
Different engagement methods produce different handover data:
QR Code Handover
For QR-based engagement, the handover contains the device engagement bytes:
QRHandover = DeviceEngagementBytes
NFC Handover
For NFC-based engagement, the handover includes NFC-specific messages:
NFCHandover = [
HandoverSelectMessage, // NDEF handover select
HandoverRequestMessage // NDEF handover request (if any)
]
OID4VP Handover
For OpenID4VP integration, the handover binds to the OAuth flow:
OID4VPHandover = [
ClientIdHash, // Hash of client_id
ResponseUriHash, // Hash of response_uri
Nonce // Presentation nonce
]
Accessing Transcript Data
The session transcript is managed internally by the IDK. When needed, you can access engagement-level information:
- Android/Kotlin
- iOS/Swift
val engagement = engagementManager.activeEngagement.value
// Get device engagement
val deviceEngagement: CborEncodedItem<DeviceEngagement> = engagement!!.getDeviceEngagement()
// Get ephemeral key
val ephemeralKey: CoseKeyType = engagement.getEphemeralKey()
let engagement = engagementManager.activeEngagement.value
// Get device engagement
let deviceEngagement = try await engagement!.getDeviceEngagement()
// Get ephemeral key
let ephemeralKey = try await engagement!.getEphemeralKey()
Security Considerations
Ephemeral Keys
Each session uses fresh ephemeral keys. This ensures that even if an attacker captures a valid response, they cannot replay it in a new session because the ephemeral keys will be different.
Handover Binding
The handover data binds the transcript to the specific engagement method used. A response created for a QR engagement cannot be used in an NFC session.
Reader Key Inclusion
When the reader provides an ephemeral key (for mutual encryption), it's included in the transcript. This prevents man-in-the-middle attacks where an attacker might try to intercept and relay sessions.
Debugging Session Issues
When session verification fails, common causes include:
| Issue | Cause | Solution |
|---|---|---|
| Transcript mismatch | Different engagement bytes | Ensure both parties use identical device engagement |
| Missing reader key | Key not included in transcript | Verify reader key is provided when expected |
| Wrong handover type | Handover doesn't match engagement | Use correct handover for the engagement method |
| Encoding differences | Non-deterministic CBOR | Ensure deterministic CBOR encoding |
Best Practices
When working with mDoc sessions:
- Use fresh ephemeral keys: Never reuse ephemeral keys across sessions
- Let the IDK manage transcripts: The IDK handles transcript computation internally
- Validate before processing: A transcript mismatch indicates a potential security issue
- Log security events: Track transcript mismatches for security monitoring