Making your network secure
Using wireless communication in your project is very convenient, but it also opens up the possibility of others sniffing your data, or even sending packets into your network to influence your project. For this reason, securing your network with proper encryption methods is an important step that is best taken right away (since it is easy to keep postponing it otherwise).
Fortunately, the XBee modules make securing your network easy and handle all the details automatically. There are a few concepts you need to understand, though.
When you enable security in your XBee module (by setting the EE
configuration value to 1
), most packets being sent will be encrypted (preventing others from reading the messages) and protected by a message integrity code (preventing others from inserting messages into your network). Special network-management packets (such as beacons, join requests, and so on) are not encrypted, nor are the lowest level packet headers, but the actual data you send is always secured.
This encryption happens using a secret key, called the network key (NK
). All members of the network must know this key to allow sending and receiving messages. This network key can be configured on the coordinator by setting the NK
configuration value. The default value of 0
causes the coordinator to select a random key when it creates a network, which should be sufficient in most cases.
Distributing the network key
When a module joins the network, it automatically receives the network key from the so-called trust center. The trust center is responsible for distributing network keys throughout the network when a node joins, or when the key is changed.
In XBee networks, the trust center always runs inside the coordinator, but the ZigBee protocol itself makes provision for running the trust center in another module as well. The ZigBee specification also allows preconfiguring the network key on all nodes, but the XBee firmware does not currently support this.
By default (with the KY
configuration value set to its default of 0
), the trust center sends the network key to joining nodes without using any encryption. This obviously poses a security risk: if someone can spy on your network traffic while your modules are joining the network, they can see your network key. Even more, an attacker could simply have his own module join the network and the network key would be sent to him, unencrypted.
To reduce this risk, you can configure your network to not allow new nodes to join normally, and only enable joining briefly when you have a new node to add. The network will still be vulnerable during these brief periods, but if the network is not compromised while joining is enabled, it will remain secure while joining is disabled. Refer to the Disabling network joining section for more info on how to disable joining.
Trust center link key
To further secure the network and avoid having to send the network key unencrypted, ZigBee defines a second key, called the trust center link key. This key is manually configured in each module (using the KY
configuration value) before it creates or joins the network. The trust center then uses this key to encrypt the network key when it is sent to new nodes joining the network. Eavesdroppers, not knowing the trust center link key, will not be able to decrypt the network key and so cannot read any of your data.
On XBee modules, there is a single trust center link key that must be known to all joining modules. The ZigBee protocol also allows for using a different trust center link key for each module, which would require more extensive configuration, but this is not supported by the current XBee ZB firmware.
Note
There is a third kind of key in the ZigBee protocol: an application link key. One of these keys can exist for every pair of modules in the network and allows additional end-to-end encryption (on top of the existing network encryption). This encryption is referred to as APS encryption in the XBee documentation and allows two modules to privately communicate, without allowing intermediate routers or other modules that are joined into the network to decrypt their messages.
Currently, the XBee firmware does not support these application link keys, so they will not be discussed any further.
Trust center terminology differences
It turns out there is a bit of a discrepancy between the XBee documentation and the ZigBee protocol specification around the concept of the trust center.
According to the ZigBee specification, a trust center is always needed to distribute the network key to newly joining nodes (unless the network key is already preconfigured on all nodes, which the XBee modules do not currently support). Additionally, the trust center can be used to distribute application keys or propagate a network key change throughout the entire network.
In the XBee documentation, distributing the network key to newly joining nodes is assumed to be done by the coordinator, even if the trust center is not enabled (controlled through the EO
configuration value). Enabling the trust center seems to be needed only to allow propagating network key changes.
Selecting encryption keys
When selecting a random key, be sure to always select a full-length key. It is possible to enter a shorter key in the KY
and NK
configuration values and a lot of the examples in the XBee documentation also do this. However, if you enter, for example, ABCD
as a key, it will be prepended with zeroes, so the actual key will end up being 0000000000000000000000000000ABCD
. This severely limits the security—a four-digit key like this can be brute-forced in a matter of seconds using a regular computer.
A strong key should be properly random and be 32 (hexadecimal) digits long (which is 16 bytes or 128 bits). Keys such as these are effectively impossible to crack using brute force, even when using current supercomputers.
Tip
If you have the OpenSSL software installed (the default on most Linux and OS X systems), you can easily generate a random key using the openssl
command line utility:
$ openssl rand -hex 16 077ef3b3e5121efa166445c63e18538d
Setting up your secure network
Now that you understand how security works in a ZigBee network, you can go ahead and restart your network with security enabled. To enable optimal security using a trust center link key, make the following configuration changes to both the coordinator and the router node (in either order):
- Configure
EE=1
- Configure
KY
(the trust center link key) to a randomly selected key. All modules should use the same key here.
For example:
Note that the KY
value can only be set, never read back, so be sure to store the key you set somewhere to allow adding new nodes to your network later.
Changing these values will automatically cause the modules to leave the current network and create a new network (coordinator) or find a new network to join (router).
After a few seconds, the new network should be formed. You can again transfer your Hello, world!
message, but in a secure way this time.
Disabling network joining
By default, XBee modules allow new modules to join the network at any time. If you configured a trust center link key, joining is of course limited to nodes that know this secret key, preventing unauthorized access to your network.
However, as an additional layer of security (or, when not using a trust center link key, the primary layer), you can also disable all join attempts after you started your network and joined your devices. You can briefly re-enable joining later when you intend to add a new device to your network.
When a device wants to join a network, it searches for an existing router (or coordinator) that allows joining. Whether this is allowed depends on the NJ
configuration value:
- When
NJ
is0
, joining is disabled - When
NJ
is0xff
, joining is enabled - When a router joins a network, and its
NJ
value is not0
or0xff
, the router allows joining forNJ
seconds - When the
NJ
parameter is changed, joining is again enabled for that many seconds - When the commissioning button is pressed twice quickly, joining is enabled for one minute
The NJ
value is not a global value for the entire network, but each node has its own value and can decide on its own whether to allow new nodes to join. Even if the coordinator has joining disabled, the trust center will still send keys to nodes that joined through another router.
In general, it is a good idea to set NJ=0
on all modules by default, and then change the value on a nearby router or the coordinator (or use the commissioning button) whenever you need to add a node to the network.
Note that, for end devices, there is also a special rejoin procedure; refer to Chapter 6, Finishing Touches and the product manual for more information about this.