JSON-based perfect forward secrecy stream
E2EE (Endpoint to Endpoint Encryption)
= HKDF(algo=connectionHashAlgo, secret=masterKey, message=label + clientNonce + serverNonce + seed)
- Encoding = Base64Encode(JSON_Stringify(input))
- Decoding = JSON_Parse(Base64Decode(input))
- Direction : Client -> Server
- ephemeralAlgorithm
- ephemeralClientPublicKey
- availableEncryptionAlgorithms (Array order is priority)
- availablePrfAlgorithms (Array order is priority)
- available
- clientNonce
- Direction : Server -> Client
- masterSecret = ECDH(ephemeralServerPrivateKey, ephemeralClientPublicKey)
- serverHandshakeKey = DeriveSecret(masterSecret, "server-handshake")
- (initial) wrappedTrafficSecretKey = DeriveSecret(masterSecret, "wrapped-traffic-key", firstWrappedTrafficSecretSalt)
- (initial) wrappedTrafficSecretIV = DeriveSecret(masterSecret, "wrapped-traffic-iv", firstWrappedTrafficSecretSalt)
- signatureAlgorithm
- serverPublicKey
- protected : JSON-Base64 Encoded String
- ephemeralServerPublicKey
- negotiatedEncryptionAlgorithm
- negotiatedPrfAlgorithm
- serverNonce
- encrypted : (= Encrypt(serverHandshakeKey, ...))
- serverCertificate (User defined metadata)
- firstWrappedTrafficSecretSalt
- extensions
- payloadSignature (= SIGN(serverPublicKey, [protectedHeader, protectedData]))
- Direction : Client -> Server
- masterSecret = ECDH(ephemeralClientPrivateKey, ephemeralServerPublicKey)
- serverHandshakeKey = DeriveSecret(masterSecret, "server-handshake")
- (initial) wrappedTrafficSecretKey = DeriveSecret(masterSecret, "wrapped-traffic-key", firstWrappedTrafficSecretSalt)
- (initial) wrappedTrafficSecretIV = DeriveSecret(masterSecret, "wrapped-traffic-iv", firstWrappedTrafficSecretSalt)
...
- Direction : Anyone -> Other
- Wrapping Key = wrappedTrafficSecret
- seed = random 32byte
wrappedTrafficSecret = DeriveSecret(wrappedTrafficSecret, "application-traffic", seed)
- Direction : Server -> Client
- Key = application_traffic_secret
- Direction : Client -> Server
- Key = client_application_traffic_secret