{"id":32246,"date":"2017-06-21T03:48:37","date_gmt":"2017-06-21T07:48:37","guid":{"rendered":"http:\/\/www.opensource.im\/uncategorized\/practical-iot-cryptography-on-the-espressif-esp8266-hackaday.php"},"modified":"2017-06-21T03:48:37","modified_gmt":"2017-06-21T07:48:37","slug":"practical-iot-cryptography-on-the-espressif-esp8266-hackaday","status":"publish","type":"post","link":"https:\/\/euvolution.com\/open-source-convergence\/cryptography\/practical-iot-cryptography-on-the-espressif-esp8266-hackaday.php","title":{"rendered":"Practical IoT Cryptography on the Espressif ESP8266 &#8211; Hackaday"},"content":{"rendered":"<p><p>    The Espressif ESP8266 chipset makes three-dollar Internet of    Things development boards an economic reality. According to    the popular automatic firmware-building site nodeMCU-builds, in the last    60 days there have been 13,341 custom firmware builds for that    platform. Of those, only 19% have SSL support, and 10% include    the cryptography module.  <\/p>\n<p>    Were often critical of     the lack of security in the IoT sector, and frequently    cover botnets    and     other attacks, but will we hold our projects to the same    standards we demand? Will we stop at identifying the problem,    or can we be part of the solution?  <\/p>\n<p>    This article will focus on applying AES encryption and hash    authorization functions to the MQTT protocol using the popular    ESP8266 chip running NodeMCU firmware. Our purpose is not to    provide a copy\/paste panacea, but to go through the process    step by step, identifying challenges and solutions along the    way. The result is a system thats end-to-end encrypted and    authenticated, preventing eavesdropping along the way, and    spoofing of valid data, without relying on SSL.  <\/p>\n<p>    Were aware that there are also more powerful platforms that    can easily support SSL (e.g. Raspberry Pi, Orange Pi,    FriendlyARM), but lets start with the cheapest hardware most    of us have lying around, and a protocol suitable for many of    our projects. AES is something you could implement on an AVR if    you needed to.  <\/p>\n<p>    MQTT is a lightweight messaging protocol that runs on top of    TCP\/IP and is frequently used for IoT projects. Client devices    subscribe or publish to topics (e.g.    sensors\/temperature\/kitchen), and these messages are relayed by    an MQTT broker. More information on MQTT is available on their webpage or in        our own getting-started series.  <\/p>\n<p>    The MQTT protocol doesnt have any built-in security features    beyond username\/password authentication, so its common to    encrypt and authenticate across a network with SSL. However,    SSL can be rather demanding for the ESP8266 and when enabled,    youre left with much less memory for your application. As a    lightweight alternative, you can encrypt only the data payload    being sent, and use a session ID and hash function for    authentication.  <\/p>\n<p>    A straightforward way to do this is using Lua and the NodeMCU    Crypto module, which includes support for    the AES algorithm in CBC mode as well as the HMAC hash function.    Using AES encryption correctly requires three things to produce    ciphertext: a message, a key, and an initialization vector    (IV). Messages and keys are straightforward concepts, but the    initialization vector is worth some discussion.  <\/p>\n<p>    When you encode a message in AES with a static key, it will    always produce the same output. For example, the message    usernamepassword encrypted with key 1234567890ABCDEF might    produce a result like E40D86C04D723AFF. If you run the    encryption again with the same key and message, you will get    the same result. This opens you to several common types of    attack, especially pattern analysis and replay attacks.  <\/p>\n<p>    In a pattern analysis attack, you use the knowledge that a    given piece of data will always produce the same ciphertext to    guess what the purpose or content of different messages are    without actually knowing the secret key. For example, if the    message E40D86C04D723AFF is sent prior to all other    communications, one might quickly guess it is a login. In    short, if the login system is simplistic, sending that packet    (a replay attack) might be enough to identify yourself as an    authorized user, and chaos ensues.  <\/p>\n<p>    IVs make pattern analysis more difficult. An IV is a piece of    data sent along with the key that modifies the end ciphertext    result. As the name suggests, it initializes the state of the    encryption algorithm before the data enters. The IV needs to be    different for each message sent so that repeated data encrypts    into different ciphertext, and some ciphers (like AES-CBC)    require it to be unpredictable  a practical way to accomplish    this is just to randomize it each time. IVs do not have to be    kept secret, but its typical to obfuscate them in some way.  <\/p>\n<p>    While this protects against pattern analysis, it doesnt help    with replay attacks. For example, retransmitting a given set of    encrypted data will still duplicate the result. To prevent    that, we need to authenticate the sender. We will use a public,    pseudorandomly generated session ID for each message. This    session ID can be generated by the receiving device by posting    to an MQTT topic.  <\/p>\n<p>    Preventing these types of attacks is important in a couple of    common use cases. Internet controlled stoves exist, and    questionable utility aside,     it would be nice if they didnt use insecure commands.    Secondly, if Im datalogging from a hundred sensors, I dont    want anyone filling my database with garbage.  <\/p>\n<p>    Implementing the above on the NodeMCU requires some effort. You    will need firmware compiled to include the crypto module    in addition to any others you require for your application. SSL    support is not required.  <\/p>\n<p>    First, lets assume youre connected to an MQTT broker with    something like the following. You can implement this as a    separate function from the cryptography to keep things clean.    The client subscribes to a sessionID channel,    which publishes suitably long, pseudorandom session IDs. You    could encrypt them, but its not necessary.  <\/p>\n<p>    Moving on, the node ID is a convenient way to help identify    data sources. You can use any string you wish though:    nodeid = node.chipid().  <\/p>\n<p>    Then, we set up a static initialization vector and a key. This    is only used to obfuscate the randomized initialization vector    sent with each message, NOT used for any data. We also choose a    separate key for the data. These keys are 16-bit hex, just    replace them with yours.  <\/p>\n<p>    Finally well need a passphrase for a hash function well be    using later. A string of reasonable length is fine.  <\/p>\n<p>    Well also assume you have some source of data. For this    example it will be a value read from the ADC. data =    adc.read(0)  <\/p>\n<p>    Now, we generate a pseudorandom initialization vector. A    16-digit hex number is too large for the pseudorandom number    function, so we generate it in two halves (16^8 minus 1) and    concatenate them.  <\/p>\n<p>    We can now run the actual encryption. Here we are encrypting    the current initialization vector, the node ID, and one piece    of sensor data.  <\/p>\n<p>    Now we apply the hash function for authentication. First we    combine the nodeid, iv,    data, and session ID into a single message, then    compute a HMAC SHA1 hash using the passphrase we defined    earlier. We convert it to hex to make it a bit more    human-readable for any debugging.  <\/p>\n<p>    Now that both encryption and authentication checks are in    place, we can place all this information in some structure and    send it. Here, well use comma separated values as its    convenient:  <\/p>\n<p>    When we run the above code on an actual NodeMCU, we would get    output something like this:  <\/p>\n<p>    All together, the encryption program is as follows (MQTT    sections excluded for clarity):  <\/p>\n<p>    Now, your MQTT broker doesnt know or care that the data is    encrypted, it just passes it on. So, your other MQTT clients    subscribed to the topic will need to know how to decrypt the    data. On NodeMCU this is rather easy. Just split the received data into strings via the    commas, and do something like the below. Note this    end will have generated the session ID so already knows it.  <\/p>\n<p>    Then compare the received and computed HMAC, and regardless of    the result, invalidate that session ID by generating a new one.  <\/p>\n<p>    For a little variety, consider how we would handle decryption    in Python, if we had an MQTT client on the same virtual machine    as the broker that was analysing the data or storing it in a    database. Lets assume youve received the data as a string    payload, from something like the excellent Paho MQTT Client for Python.  <\/p>\n<p>    In this case its convenient to hex encode the encrypted data    on the NodeMCU before transmitting. So on the NodeMCU we    convert all encrypted data to hex, for example:    encrypted_iv = crypto.toHex(crypto.encrypt(\"AES-CBC\",    ivkey, iv, staticiv))  <\/p>\n<p>    Publishing a randomized sessionID is not discussed below, but    is easy enough using os.urandom() and the Paho MQTT Client. The decryption is handled as    follows:  <\/p>\n<p>    Now we have a system that sends encrypted, authenticated    messages through an MQTT server to either another ESP8266    client or a larger system running Python. There are still    important loose ends for you to tie up if you implement this    yourself. The keys are all stored in the ESP8266s flash    memory, so you will want to control access to these devices to    prevent reverse engineering. The keys are also stored in the    code on the computer receiving the data, here running Python.    Further, you probably want each client to have a different key    and passphrase. Thats a lot of secret material to keep safe    and potentially update when necessary. Solving the key    distribution problem is left as an exercise for the motivated    reader.  <\/p>\n<p>    And on a closing note, one of the dreadful things about writing    an article involving cryptography is the possibility of    being wrong on the Internet. This is a fairly    straightforward application of the tested-and-true AES-CBC mode    with HMAC, so it should be pretty solid. Nonetheless, if you    find any interesting shortcomings in the above, please let us    know in the comments.  <\/p>\n<p><!-- Auto Generated --><\/p>\n<p>More here:<br \/>\n<a target=\"_blank\" href=\"http:\/\/hackaday.com\/2017\/06\/20\/practical-iot-cryptography-on-the-espressif-esp8266\/\" title=\"Practical IoT Cryptography on the Espressif ESP8266 - Hackaday\">Practical IoT Cryptography on the Espressif ESP8266 - Hackaday<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p> The Espressif ESP8266 chipset makes three-dollar Internet of Things development boards an economic reality. <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1600],"tags":[],"class_list":["post-32246","post","type-post","status-publish","format-standard","hentry","category-cryptography"],"_links":{"self":[{"href":"https:\/\/euvolution.com\/open-source-convergence\/wp-json\/wp\/v2\/posts\/32246"}],"collection":[{"href":"https:\/\/euvolution.com\/open-source-convergence\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/euvolution.com\/open-source-convergence\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/euvolution.com\/open-source-convergence\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/euvolution.com\/open-source-convergence\/wp-json\/wp\/v2\/comments?post=32246"}],"version-history":[{"count":0,"href":"https:\/\/euvolution.com\/open-source-convergence\/wp-json\/wp\/v2\/posts\/32246\/revisions"}],"wp:attachment":[{"href":"https:\/\/euvolution.com\/open-source-convergence\/wp-json\/wp\/v2\/media?parent=32246"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/euvolution.com\/open-source-convergence\/wp-json\/wp\/v2\/categories?post=32246"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/euvolution.com\/open-source-convergence\/wp-json\/wp\/v2\/tags?post=32246"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}