Securing Communication Between Devices and the IoT Platform

  • By Inosh Perera
  • 14 Sep, 2017

Introduction

As the Internet of Things (IoT) is becoming a hot topic across many industries, more and more devices entering the market are connected and shared among many users. In this rapidly growing space, thousands and millions of things are being connected. Therefore, it is easy to lose sight of the security aspect of the devices that are getting connected. With emerging DDoS attacks on IoT botnets, it is important that organizations chose IoT solutions that have proper identity and security functionality. Let's take a look at how WSO2 IoT Server, an open source IoT platform addresses security requirements of things in this connected world.

WSO2 IoT Platform

WSO2 IoT platform is an enterprise grade open source platform capable of managing both mobile and IoT devices. WSO2 IoT platform inherits superior API management, identity management and analytics capabilities from WSO2 products on top of which, IoT adds the device management capabilities to the picture. In IoT platform, the device management is done through the communication between two important entities; namely, the IoT server and the IoT agents.

WSO2 IoT Server

IoT server provides a complete set of REST APIs to successfully manage devices and the device manufacturers can write their own device types and plugin these device types to IoT server in order to manage those devices. The devices will communicate with the IoT server to get themselves

WSO2 IoT Agent

For all these communication to happen, there must be an entity in the device that knows how to contact the server, enroll with it, send the devices sensor data and process any command sent by the server. This is handled by the IoT agents that is installed on to the devices. Based on the device platform the agent can be written in any appropriate programming language and the agent will consume the device management APIs exposed by the IoT server. Let's take a closer look at different types of communication that happens in the IoT server,

Modes of Communication

All communication that happens in WSO2 IoT Server can be broken down into two main areas as illustrated in Figure 1:

  1. Device to server
  2. Server to apps or external systems

Figure 1

The WSO2 IoT server, communicates with external systems such as LDAPs or databases when necessary and this communication is done securely. However, the focus of this article is to discuss the security mechanisms that are available to protect communication between the device and the server. Therefore let's take a look at how WSO2 IoT server handles the device-server communication and does it in a secure way.

Devices and Server Communication

At the heart of IoT lies the connectivity and connectedness of devices or things with an IoT platform. Devices connect to WSO2 IoT Server to pump new events that happen in real time or to check for operations and policies that need to be carried out on the device.

Today, resources are increasingly exposed as APIs and with the rise of these APIs, attempts to steal corporate data and misuse resources are increasing. In the world of IoT, these devices need to communicate constantly or periodically with the server and these connections are typically made through public networks with the use of protocols, such as MQTT, HTTP, or XMPP. Regardless of the communication method, they must be secured with an extra layer of security to protect the corporate data being stolen.

Since the device to server communication happens over a public network, it is vital to protect the channel that is used to transmit the data. To make sure the channel is secure, it is important to use SSL/TLS between the device and the server and ensure only the intended parties can read the messages being transmitted. Other than this fundamental protection at the transport layer, it is important that the server and the device identify and validate each other to ensure that only the authorized devices/users are accessing the protected resources. This is where proper authentication comes into play. In this article we will look at two forms of authentication:

  1. Token-based authentication
  2. Certificate-based authentication

Token-Based Authentication

A token can be thought of as a string created by an authentication server that can be used to identify the device and its right to access a protected resource. Typically, in this flow, the device may send some secret credential, which will be identified by the server and after validating the credentials the device may be given a token that can be used to access protected resources. One such industry standard protocol is OAuth.

OAuth is an authorization standard that is token based and is normally used together with an authentication means to ensure resource security. Any request that comes to an OAuth server for authorization must first be authenticated by an authentication server. If the user is authenticated and authorized, a token is issued. This allows the device to communicate with APIs based on the permissions given to the token.

When accessing protected resources, it is important to authorize the devices making the request. OAuth facilitates this exact requirement. Another important feature of OAuth is its simple design that allows low-powered IoT devices to authenticate and authorize using minimum processing power and resources. WSO2 API Manager to protect backend APIs that the devices use to communicate. Some devices that are managed by the IoT Server relies on OAuth for securely communicating with the backend. The WSO2 IoT Server is capable of managing Android devices out of the box and this is done with an agent called the device management agent. This agent will receive commands to be executed on the device from the IoT Server. Another form of device monitoring is done by using an agent called the Android sense agent that monitors the sensors of the Android devices and reports these values to the IoT Server so they can be analyzed and perform any operations on the device. In both these agents, it is vital to protect the communication between the device and the server as they contain corporate data that must be kept secure. This is where OAuth comes to the rescue. Let's take a look at how Android devices securely communicate with the IoT Server with the use of OAuth as described in Figure 2.

Figure 2

  1. First, the device needs to have a special credential set [3] called client credentials to
    generate an OAuth token. For this, the device first contacts the dynamic client registration [1] API together with a list of APIs that it needs to subscribe.
  2. At the API key manager, the user credentials are verified by connecting to the relevant user store.
  3. If the user credentials are valid, the user is subscribed to the requested APIs by calling the API store.
  4. After the user is subscribed, the client credentials are generated and sent back to the device.
  5. Next, the device makes a request together with scopes [6], client credentials, and user credentials to get an access token.
  6. The key manager validates the login credentials against a defined user store. In addition to validating the user credentials, the scope requested is also validated. Each user has predefined roles and their associated permissions. These permissions correspond to the API scopes and when the user requests a token with a set of scopes, the key manager checks if the user has the necessary permissions for the requested scopes.
  7. A token pair is sent to the device that consists of an access token to access the permitted APIs and a refresh token to refresh the access token when it expires.
  8. Once the device has an access token, it can call the protected APIs that are accessible by the scopes requested in Steps 5 and 6.
  9. When a request to access an API is received together with an access token, the key manager will check if the access token is valid and it will also check if it has the associated permissions to access the requested API. If so, the access if provided.

The above use case shows a simple yet secure OAuth implementation that protects backend APIs and resources. Due to dynamic client credential generation [1], the need to store client credentials in a device prior to an enrollment is eliminated. Since each device is issued a separate client credential, instead of sharing the same client credential, even if one device’s client credentials are compromised, the rest of the devices are not affected.

Certificate-Based Authentication

Similar to using tokens for authentication, it is possible to use certificates in the authentication flow to identify devices and the server uniquely. When SSL is used in the communication, the device has a way to identify and verify the server. The primary objective of certificate-based authentication is to create a certificate for each device and use it in the server to identify and authenticate each device. Therefore, with SSL and certificate-based authentication, it is possible to create a mutual authentication where the server can identify the device with the device identity certificate and the device can identify the server with the SSL certificates. This provides a very secure communication channel that is ideal for enterprise data communication. One of the most common ways of implementing certificate-based authentication is through the use of SCEP protocol; let’s consider what it is and why it is important.

Simple certificate enrollment protocol (SCEP) [2] is a powerful protocol that allows devices to generate device identity certificates on the fly. First, the device authenticates with an authentication server. Once it is authenticated, the server allows the device to send a certificate signing request (CSR), which will be signed by a CA certificate of the server. This allows the server to trust the device’s certificate since it was signed by the device, and the device will trust the server as the servers certificates are pre-installed on the device. SCEP comes in handy for IoT devices as the device identity can be generated on the fly and dynamically for each device. Since there is a mutual trust between the server and the device, the communication channel becomes extremely secure.

SCEP is also supported in WSO2 IoT Server and, as a result, certificate-based authentication is facilitated. Platforms, such as iOS, actively rely on SCEP capabilities in WSO2 IoT Server to enroll and authenticate. Let's take a look at how SCEP works and how SCEP is implemented in IoT Server, especially in the case of iOS device management. SCEP came into existence to solve the issue of scalably delivering device specific certificates to network devices such as routers. The end goal of the protocol is to deliver a device specific certificate to a device that can be used to authenticate and authorize a user. Let's take a look at the flow of SCEP communication to get a better understanding (Figure 3).

Figure 3

  1. The device at the enrollment stage needs to download and install the self-signed root CA certificate of the IoT Server.
  2. The user first types in the user credentials on a device (username and password), and this is passed to WSO2 IoT Server.
  3. WSO2 IoT Server validates the user credentials.
  4. If the credentials are valid, the server will generate a one time token and will be returned to the device. The server expects the token to be used in future communication with the server.
  5. The device generates a private key and a corresponding Certificate Signing Request (CSR).
  6. The device passes the CSR together with the one time token to the server.
  7. WSO2 IoT Server uses the inbuilt CA server facilities to sign the CSR and issues a certificate to the device. Note that in addition to issuing the certificate, the server also stores the certificate generated against the user it belongs to for future reference.
  8. At this point the device has a key pair (public and private) that is trusted by the IoT server and since in Step 1 the CA certificate is installed on the device, the device too can trust the server. After this point the device can send a verification header signed with its private key that can be used to validate the server to identify the devices.

Based on above explanation, at the end of the process, the device has an identity certificate to identify itself to the loT Server, which is trusted by the server. When communicating with the server, the device identity certificate is sent as a header to identify the device and the message content is typically signed by the private key of the device identity. Since the server has the corresponding public key, the server can verify if the device has actually signed the content. Now the device can call the protected APIs securely.

Best Practices with SCEP

It's important to note that since SCEP is considered an unauthenticated protocol, no other authentication takes place at the time a certificate is signed,. To overcome this issue, an added layer of security is provided where when a CSR is submitted, the user credentials are first passed to the server and validated. The server will first validate if the user credentials are valid, and if so, the certificate is signed and issued. To track down the request and certificate issued a challenge token will also be associated with the certificate, which will be validated when the requests are sent.

Other than OAuth and SCEP, WSO2 IoT Server supports basic authentication and mutual TLS authentication out of the box too. Due to the extensible nature of the authentication logic, it is possible for organizations to build there own authentication scheme to secure communication with the server.

Adding Your Custom Security Scheme

There are situations where out of the box authentication mechanisms are not enough to facilitate a custom requirement. In such cases, it is important that the IoT Server provides enough extensibility to plugin in your own authentication methods. WSO2 IoT Server provides such extensibility and this let’s you to write your own logic that allows you to connect to an external system to do your authentication for authentication requests coming to the server. For example, let’s imagine a situation where we have a customized device that always appends an authentication header value to requests being sent to the IoT Server. And in order to validate the authenticity of the device, we need to send this custom header value to a web service provided by the device manufacturer. In such a situation, we can write an extension, where it will sit between the IoT Server and the device and do the header validation by talking to an external system. Let's take a look at how we can write a custom authenticator and plug it into the IoT Server.

How To Plugin Your Own Authentication Scheme?

Any request that is made by a device to the IoT Server backend, first goes through the API gateway. In the API gateway, there are multiple handlers [5] that perform different tasks and these handlers are engaged one by one sequentially as the request flow through. One of these handlers is the APIAuthenticationHandler handler that performs the OAuth authentication under default message flow. After writing a custom handler, we will need to replace the APIAuthenticationHandler with our custom handler so that our authentication logic happen prior to other core API management tasks, such as API throttling and usage statistics collection. Figure 4 illustrates the flow between handlers prior to after the custom handler is engaged.

Figure 4

Now that we are aware of how the messages flow between handlers, let's see how the entire flow looks like, for example, when validating a custom header to authenticate a device (Figure 5).

Figure 5

  1. The device makes a request to the server to access a secure resource, and it will first come to the API gateway. When sending this request, the device can add a custom header that needs to be validated to authenticate the device.
  2. The API gateway includes a custom handler that we wrote, which includes a custom logic to verify the device. First, the handler needs to engage with the API that needs to be protected.
  3. When engaged, the custom logic inside the handler validates the custom header. For example, the handler may forward this custom header value that was sent by the device to an external system and authenticate the device.
  4. After this, the details of the user that was just authenticated needs to be passed to the IoT Server backend in order to properly handle the original request. For this, we will be creating a JWT token.
  5. Pass the original request to WSO2 IoT Server along with the JWT token that was just created.
  6. WSO2 IoT Server validates the JWT token and provides access to the original request.

You can find a sample implementation of a custom authentication handler here [4]. Let’s go through this sample by following the above steps to understand the code more clearly. Note that in this project, our custom handler logic is written in the CustomAuthenticationHandler class and its package name is org.wso2.carbon.authenticator.

  1. As described in our first step, the device sends a custom header value to the server and this is intercepted by a gateway.
  2. Place the custom logic (custom handler) in the gateway and engage the handler in the API you want to protect. To do this, first locate the API definition related to the API that you want to modify in the /repository/deployment/server/synapse-configs/default/api directory, go to the handles tag, insert the <handler class="org.wso2.carbon.authenticator.CustomAuthenticationHandler"/> tag, and remove the <handler class="org.wso2.carbon.apimgt.gateway.handlers.security.APIAuthenticationHandler"/> handler.
  3. When the custom handler engages with the API, the custom logic is executed. Let's look at the structure of a custom handler. Whenever a request comes into the handler, the handleRequest method is executed. This method gets a MessageContext object, which contains the request details from the device. In this example, we extract the header values as shown below:
  4.   
    public boolean handleRequest(MessageContext messageContext) {
            if (log.isDebugEnabled()) {
                log.debug("CustomAuthenticationHandler handleRequest  
                called");
            }
            return authenticate(messageContext);
    }
    
    private boolean authenticate(MessageContext synCtx) {
    
            Map headers = getTransportHeaders(synCtx);
            String authHeader = (String) headers.get(CUSTOM_AUTHENTICATION_HEADER);
    
    
            // These values must be passed by the user and these variables has to be populated.
            String tenantDomain = "carbon.super";// This can be the teant you created for example marketing or sales
            String username = "admin";
    
    
            // Fill here with the custom authentication logic as you wish. For example call an external system to
            // validate a value that comes in the CUSTOM_AUTHENTICATION_HEADER. After authenticating, the information
            // about the user needs to be passed to the backend, therefore a JWT token is generated.
    
            //if (authHeader.startsWith("custom_authenticated_value")) {
                try {
                    headers.put(X_JWT_ASSERTION, AuthenticationUtils.createJWTToken(username, tenantDomain));
                    return true;
                } catch (CustomAuthenticatorException e) {
                    log.error("Error while attempting to authenticate the request.", e);
                    return false;
                }
            //}
            //return false;
        }
    
    

    After extracting the necessary details from the request, you can authenticate the details sent as you wish.

    Once the authentication is successful, you can return the result from this method. In addition, after the authentication is successful, you need to add details about the authenticated user to the request in the form of a JWT token so that the IoT server has details about the user and knows that the request is authenticated. This is done by calling the method AuthenticationUtils.createJWTToken utility, and it expects the username and tenant domain to be passed to it. Since the code inside the util class doesn't need to be modified, we will not be focusing on this.

  5. WSO2 IoT Server can now process the request and provide access to the required resource.

How To Support Multi Factor Authentication?

Multifactor authentication can be thought of as an additional layer of security that can be coupled with an existing authentication mechanism. The importance of multifactorial is that if one factor is compromised, the additional layer will guarantee that the secured resources are not compromised. Multifactor authentication is commonly used when logging into different services, such as email where the user must provide user credentials. Moreover, they can choose to have an additional layer of security by combining their mobile number to the system where the server will send a one time token to the user's phone and the user must enter this token to complete the authentication.

We can also achieve multi-factor authentication through a custom authentication handler as mentioned previously. Here, the client initially sends the first set of credentials to validate and after authenticating the user. Therefore, the custom logic can be written to generate and store the one time token. The token is passed through a device, such as an SMS gateway, where it delivers the token to the device. The device can then forward this token back to the server and the custom handler validates the token against its stored value. Due to the extensible nature of the authentication mechanism, it is possible for you to implement a custom logic and link with any external system as you wish.

Summary

To summarize the discussion, it’s evident that WSO2 IoT Server has powerful out-of-the box mechanisms on IoT security to protect end-to-end communication and also allows organizations to customize their capabilities through the provided extension points. These capabilities allow organizations to have a very secure and scalable IoT infrastructure in this rapidly growing industry.

References