4.8 KiB
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. This easily allows Alice to verify Bob's key, but does not give Bob any information about Alice's key in order to verify it. However, Bob's device can now send to Alice's device what it thinks is her key (signed by his key, so that Alice can verify that the message actually came from his device), and Alice's device can do the verification on behalf of Bob and display the result.
Example flow:
- Alice and Bob meet in person, and want to verify each other's keys.
- Bob tells his device to display a QR code. Bob's device displays a
QR code that encodes the URL
https://matrix.to/#/<user-id>?device=<device-id>&action=verify&pubkey=<device-signing-public-key-in-base64>
(whenmx:
URLs are specced, this will be used instead). - Alice scans the QR code.
- Alice's device ensures that the user ID in the QR code is the same as the expected user ID. This can be done by prompting Alice with the user ID, or can be done automatically if the device already knows what user ID to expect. At this point, Alice's device has now verified Bob's key.
- Alice's device sends a
m.key.verification.reciprocate
message (see below) as a to-device message to Bob's device (using the user ID and device ID from the QR code.) - Bob's device fetches Alice's public key, signs it, and sends it to Alice's
device in a
m.key.verification.check_own_key
to-device message (see below). Bob's device displays a message saying that Alice wants him to verify her key, and presents a button for him to press /after/ Alice's device says that things match. - Alice's device receives the
m.key.verification.check_own_key
message, checks Bob's signature, and checks that the key is the same as her device key, as well as checking that the rest of the contents match the expected values. Alice's device displays whether the verification was successful or not. - 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.
Message types
m.key.verification.reciprocate
Tells Bob's device that Alice has verified his key, and requests that he verify Alice's key in turn.
message contents:
device_id
: the ID of the device that Alice is usingtransaction_id
: an identifier for the transaction. Must be unique on Alice's device.
FIXME: Alice's device should be allowed to expire verification requests.
m.key.verification.check_own_key
Tells Alice's device what Bob's device thinks her key is.
message contents:
key
: The key that Bob's device has for Alice's devicetransaction_id
: the transaction ID from them.key.verification.reciprocate
messagesignatures
: signature of the key and transaction ID, signed using Bob's key
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. These methods are not exclusive to each other.
Security Considerations
Step 4 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 until after Alice's device indicates success. However, users have a tendency to click on buttons without reading what the screen says. This might be addressed by:
- allowing Bob to easily undo the verification if Alice's device subsequently gives an error
- posing Bob a dummy question that he cannot answer until after Alice's device displays the check results. For example: "Does Alice's device show a cat or a dog?" Alice's device will show one or the other after it has checked the key received from Bob, forcing Bob to wait for the check to complete. (Whether a cat or a dog is displayed could be keyed to, for example, a bit in the transaction ID.)
- (possibly other ways)