You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
matrix-spec/proposals/1543-qr_code_key_verificati...

175 lines
7.9 KiB
Markdown

Key verification using QR codes
===============================
Problem/Background
------------------
Key verification is essential in ensuring that end-to-end encrypted messages
cannot be read by unauthorized parties. Traditionally, key verification is
done by comparing long strings. To save users from the tedium of reading out
long strings, some systems allow one party to verify the other party by
scanning a QR code; by doing this twice, both parties can verify each other.
In this proposal, we present a method for both parties to verify each other by
only scanning one QR code.
Proposal
--------
When Alice and Bob meet in person to verify keys, Alice will scan a QR code
generated by Bob's device. The QR code will encode both Bob's key as well as what Bob
thinks Alice's key is. When Alice scans the QR code, she will ensure that the
keys match what is expected, in which case, she relays this information to Bob,
who can then tell his device that the keys match.
Example flow:
1. Alice and Bob meet in person, and want to verify each other's keys.
2. Alice requests a key verification through her device by sending an
`m.key.verification.request` message (see
[MSC2241](https://github.com/matrix-org/matrix-doc/pull/2241)), with
`m.qr_code.show.v1`, `m.qr_code.scan.v1`, and `m.reciprocate.v1` listed in
`methods`.
3. Alice's client displays a QR code that Bob is able to scan, and an option to
scan Bob's QR code.
4. Bob's client prompts Bob to verify Alice's key. The prompt includes a QR
code that Alice can scan (if the `m.key.verification.request` message listed
`m.qr_code.scan.v1`), and an option to scan Alice's QR code (if the
`m.key.verification.request` message listed `m.qr_code.show.v1`).
5. Alice scans Bob's QR code.
6. Alice's device ensures that:
- the user ID in the QR code is the same as the expected user ID (which it
knows because it is the recipient of her `m.key.verification.request`
message),
- Bob's keys encoded in the QR code match the keys that she already has for
Bob, and
- Alice's cross-signing key matches the cross-signing key encoded in the QR
code.
If any of these checks fail, Alice's device displays an error message.
Otherwise, at this point, Alice's device has now verified Bob's key, and her
device will display a message saying that all is well.
7. Alice's device sends a `m.key.verification.start` message with `method` set
to `m.reciprocate.v1` to Bob (see below).
8. Upon receipt of the `m.key.verification.start` message, Bob's device
presents a button for him to press /after/ he has checked that Alice's
device says that things match.
9. Bob sees Alice's device confirm that the key matches, and presses the button
on his device to indicate that Alice's key is verified.
10. Both devices send an `m.key.verification.done` message.
### Verification methods
This proposal defines three verification methods that can be used in
`m.key.verification.request` messages (see
[MSC2241](https://github.com/matrix-org/matrix-doc/pull/2241)).
- `m.qr_code.show.v1`: means that the sender of the
`m.key.verification.request` message can show a QR code that the recipient
can scan. If the recipient can scan the QR code, it should allow the user to
do so. This method is never sent as part of a `m.key.verification.start`
message.
- `m.qr_code.scan.v1`: means that the sender of the
`m.key.verification.request` message can scan a QR code displayed by the
recipient. If the recipient can display a QR code, it should allow the user
to display it so that the sender can scan it. This method is never sent as
part of a `m.key.verification.start` message.
- `m.reciprocate.v1`: means that the sender can participate in a reciprocal
verification, either as initiator or responder, as described in the [Message
types](#message-types) section below.
### QR code format
The QR codes to be displayed and scanned using this format will encode URLs of
the form:
`https://matrix.to/#/<user-id>?request=<event-id>&action=verify&key_<keyid>=<key-in-base64>...&verification_algorithms=<algorithm>&verification_key=<random-key-in-base64>&other_user_key=<master-key-in-base64>`
(when `matrix:` URLs are specced, this will be used instead).
- `request`: is the event ID of the associated verification request event.
- `key_<key_id>`: each key that the user wants verified will have an entry of
this form, where the value is the key in unpadded base64. The QR code should
contain at least the user's master cross-signing key.
- `secret`: is a random single-use shared secret in unpadded base64. It must be
at least 256-bits long (43 characters when base64-encoded).
- `other_user_key`: the other user's master cross-signing key, in unpadded
base64. In other words, if Alice is displaying the QR code, this would be
the copy of Bob's master cross-signing key that Alice has.
The QR codes to be displayed and scanned, which are not a part of an in-person
verification (for example, for printing on business cards), will encode URLs of
the form:
`https://matrix.to/#/<user-id>?&action=verify&key_<keyid>=<key-in-base64>...`
In this case, only the user scanning the QR code will verify the key of the
user whose QR code was scanned; bi-directional verification is not possible.
### Message types
#### `m.key.verification.start`
Alice's device tells Bob's device that the keys are verified. The request is
MAC'ed using the verification algorithm and verification key from the QR code.
message contents:
- `method`: `m.reciprocate.v1`
- `m.relates_to`: as per [key verification framework](https://github.com/matrix-org/matrix-doc/pull/2241)
- `secret`: the shared secret from the QR code
Example:
```json
{
"method": "m.reciprocate.v1",
"m.relates_to": {
"rel_type": "m.reference",
"event_id": "!event_id_of_verification_request"
},
"secret": "shared+secret"
}
```
Note that this message could be sent by either the sender or the recipient of
the `m.key.verification.request` message, depending on which user scanned the
QR code.
### Cancellation
In addition to the cancellation codes specified in [the spec for
`m.key.verification.cancel`](https://matrix.org/docs/spec/client_server/r0.5.0#m-key-verification-cancel),
the following cancellation codes may be used:
- `m.qr_code.invalid`: The QR code is invalid (e.g. it is not a URL of the
required form)
The verification can also be cancelled with the error codes:
- `m.key_mismatch`: if the QR code has keys that do not match the expected
value
- `m.user_mismatch`: if the QR code is for a different user from what was expected
Tradeoffs/Alternatives
----------------------
Other methods of verifying keys, which do not require scanning QR codes, are
needed for devices that are unable to scan QR codes. One such method is
[MSC1267](https://github.com/matrix-org/matrix-doc/issues/1267).
Security Considerations
-----------------------
The first check in Step 6 in the example flow is to ensure that Bob does not
present a QR code claiming to be Carol's key. Without this check, Bob will be
able to trick Alice into verifying a key under his control, and evesdropping on
Alice's communications with Carol.
The security of verifying Alice's key depends on Bob not hitting the "Verified"
button (step 9 in the example flow) until after Alice's device indicates
success or failure. Users have a tendency to click on buttons without reading
what the screen says, but this is partially mitigated by the fact that it is
unlikely that Bob will be interacting with the device while Alice is scanning
and Alice's device will display the verification results immediately upon
scanning. Also, Bob's device will not display the button until it receives the
`m.key.verification.start` message that contains the shared secret from the QR
code, which means that an attacker would need to be physically present while
Alice and Bob verify. This issue can also be addressed by allowing Bob to
easily undo the verification if Alice's device displays an error.