Commit e0118f46 authored by Peter Waher's avatar Peter Waher

End-to-end cryptography

parent 974975a9
End-to-End encryption
This document outlines the XML representation of end-to-end encryption, as defined by the IEEE XMPP IoT Working Group. The XML representation is modelled
using an annotated XML Schema:
| Sensor Data ||
| ------------|----------------------------|
| Namespace: | urn:ieee:iot:e2e:1.0 |
| Schema: | [E2E.xsd](Schemas/E2E.xsd) |
Motivation and design goal
The method of end-to-end encryption (E2E) described here, is designed with the following goals in mind:
* Peers should be able to negotiate which algorithms to use.
* Hybrid algorithms should be supported, where an asymmetric cipher with a public/private key pair is used to negotiate a symmetric key for a symmetric
cipher, that is used to encrypt/decypt the payload of the stanza. The symmetric key is unique for each stanza.
* Both `message` and `iq` stanzas should be possible to encrypt, together with all their contents.
* Signatures should be used to authenticate sender.
* E2E communication is optional, and can be used where privacy or confidentiality concerns are such that E2E connections are warranted.
* Public keys should be short-lived to maintain forward secrecy. If a public/private key is broken, only stanzas encrypted with the help of that
public/private key pair are affected.
Publishing E2E Information
When a device starts, it should generate new public/private keys. Everytime it gets connected it should publish the public keys using `persence`, so that
everyone with a presence subscription is aware of the currernt public key. Everytime a new public/private key is generated, it should also publish the public
key in a new `presence`. Apart from the most receive public/private key pair, the previous pair should also be kept in memory. Since there might be a delay
in propagating the new key, it allows the recipient to receive and decrypt stanzas that have been encrypted using the previous key.
Hybrid Ciphers
Cyphers used in E2E have two components: An assymetric cipher using a public key for encryption and signature validation, and a private key for
decryption and signature generation. This cipher is used to negotiate one-time symmetric keys for a symmetric cipher used to encrypt and decrypt the
actual payload. Once the symmetric key has been used, it is discarded. The assymetric keys are regenerated as often as required by the sensitivity of
the data being communicated.
Presence instead of handshake
To avoid having to negotiate keys when setting up E2E communication, public keys are published using `presence`. This allows anyone to send a message to
the entity, without first having to do a handshake. The sender can make the decision without handshake, and the receiver will be able to decrypt it. The
number of E2E stanzas transmitted and received is the same as the number of unencrypted stanzas, plus the number of presence stanzas transmitted. While this
typically reduces the number of messages required to estblish E2E communication between peers, it is not designed for the generation of new public keys
for every single stanza. Instead, public/private keys are generated on a timely fashion, depending on context, or after concluding a series of stanzas
(a communication session), so that anyone starting a new E2E session with the entity does so using new keys. Public keys should still be short-lived,
as to not risk all historic messages to be broken, in case a public/private key pair is broken (forward secrecy).
The `rsaAes` algorithm combines RSA public/private keys with AES-256 symmetric cipher (using Cipher Block Chaining (CBC) and PKCS#7 padding) to establish
E2E between two entities. The RSA keys are used to encrypt the AES keys and initialization vectos, as well as sign the payload by the sender (with SHA-256
and PKCS#1 v1.5 padding).
When E2E encrypting a `message` stanza, it is encrypted in its entirety, and then placed in an `aes` element. This is then sent in a **normal**,
unadorned `message` stanza by itself. The only attributes transferred from the original message, is the `id` and `to` attributes. The rest is protected
inside the encrypted element.
When E2E encrypting an `iq` stanza, only the contents of the stanza is encrypted, and then placed in an `aes` element. This element is then sent in an
`iq` stanza with the same `type`, `id`, `to` and `from` attributes as the original stanza.
On both cases, the signatures are calculated on the unencrypted part of the payload that is to be encrypted. Encoding of XML text to bytes is always done
using UTF-8 encoding.
Example, when publishing public keys using `presence`:
<p2p extIp='' extPort='49790' locIp='' locPort='49790' xmlns='urn:ieee:iot:p2p:1.0'/>
<e2e xmlns='urn:ieee:iot:e2e:1.0'>
<rsaAes size='4096' mod='vyhg+bU+QqExe7QRpKWXiRG/LkOU6D/...' exp='AQAB'/>
<c xmlns='' hash='sha-256' node='...' ver='...'/>
Example, sending an E2E encrypted `iq` stanza:
<iq id='28209' type='get' to='...' from='...'>
<aes xmlns='urn:ieee:iot:e2e:1.0'
**Note**: RSA keys are large, which will cause small stanzas to become much larger when E2E encrypted. RSA and AES is available for devices that do not
support Elliptic Curve Cryptography (ECC). ECC is able to maintain the same security strength using shorter messages.
ECC p521/AES
......@@ -111,7 +111,7 @@ purposes.
<xs:attribute name="ivRsa" type="xs:base64Binary">
<xs:documentation>Random Initiation vector is encrypted using the public RSA key of the recipient.</xs:documentation>
<xs:documentation>Random Initialization vector is encrypted using the public RSA key of the recipient.</xs:documentation>
<xs:attribute name="signRsa" type="xs:base64Binary">
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment