{"id":116459,"date":"2022-10-20T09:42:01","date_gmt":"2022-10-20T09:42:01","guid":{"rendered":"https:\/\/randomnerdtutorials.com\/?p=116459"},"modified":"2022-10-20T09:43:16","modified_gmt":"2022-10-20T09:43:16","slug":"esp32-esp-now-encrypted-messages","status":"publish","type":"post","link":"https:\/\/randomnerdtutorials.com\/esp32-esp-now-encrypted-messages\/","title":{"rendered":"ESP32: ESP-NOW Encrypted Messages"},"content":{"rendered":"\n<p>In this guide, you&#8217;ll learn how to encrypt ESP-NOW messages exchanged between ESP32 boards. ESP-NOW uses the CCMP method for encryption using a Primary Master Key (PMK) and Local Master Keys (LMK).<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" fetchpriority=\"high\" decoding=\"async\" width=\"1200\" height=\"675\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2022\/09\/ESP32-ESP-NOW-Encrypted-Messages.jpg?resize=1200%2C675&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP32 ESP-NOW Encrypted Messages Arduino IDE\" class=\"wp-image-116471\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2022\/09\/ESP32-ESP-NOW-Encrypted-Messages.jpg?w=1280&amp;quality=100&amp;strip=all&amp;ssl=1 1280w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2022\/09\/ESP32-ESP-NOW-Encrypted-Messages.jpg?resize=300%2C169&amp;quality=100&amp;strip=all&amp;ssl=1 300w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2022\/09\/ESP32-ESP-NOW-Encrypted-Messages.jpg?resize=1024%2C576&amp;quality=100&amp;strip=all&amp;ssl=1 1024w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2022\/09\/ESP32-ESP-NOW-Encrypted-Messages.jpg?resize=768%2C432&amp;quality=100&amp;strip=all&amp;ssl=1 768w\" sizes=\"(max-width: 1200px) 100vw, 1200px\" \/><\/figure><\/div>\n\n\n<p>If you&#8217;re new to ESP-NOW, we recommend reading the following getting started guide first to get familiar with ESP-NOW concepts and functions on the ESP32:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><a href=\"https:\/\/randomnerdtutorials.com\/esp-now-esp32-arduino-ide\/\">Getting Started with ESP-NOW (ESP32 with Arduino IDE)<\/a><\/li><\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">CCMP Security Protocol<\/h2>\n\n\n\n<p>CCMP means Counter Mode with Cipher Block Chaining Message Authentication Code Protocol. This is an encryption protocol designed for Wireless LAN. ESP-NOW can use the CCMP method to encrypt messages. <\/p>\n\n\n\n<p>Accordingly to the <a href=\"https:\/\/docs.espressif.com\/projects\/esp-idf\/en\/latest\/esp32\/api-reference\/network\/esp_now.html?highlight=esp_now_set_pmk#security\" target=\"_blank\" rel=\"noreferrer noopener\">documentation<\/a>:<\/p>\n\n\n\n<p>&#8220;<em>ESP-NOW use <strong>CCMP <\/strong>method which can be referenced in IEEE Std. 802.11-2012 to protect the vendor-specific action frame.&#8221; <\/em><\/p>\n\n\n\n<p>The Wi-Fi device maintains a <strong>Primary Master Key (PMK)<\/strong> and several <strong>Local Master Keys (LMK)<\/strong>. The length of the keys is 16 bytes.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Primary Master Key (PMK)<\/h3>\n\n\n\n<p>PMK is used to encrypt LMK with the AES-128 algorithm. To set the PMK key of the Wi-Fi device, you can use the <span class=\"rnthl rntliteral\">esp_now_set_pmk()<\/span> function to set PMK. If PMK is not set, a default PMK will be used.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Local Master Key (LMK)<\/h3>\n\n\n\n<p>You should set the LMK of the paired device to encrypt the vendor-specific action frame with CCMP method. The maximum number of different LMKs is six. The LMK is a property of the peer, <span class=\"rnthl rntliteral\">esp_now_peer_info_t<\/span> object, and can be set on the <span class=\"rnthl rntliteral\">lmk<\/span> property as we&#8217;ll see later.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">ESP32: Getting Board MAC Address<\/h2>\n\n\n\n<p>To communicate via ESP-NOW, you need to know the MAC Addresses of the boards so that you can add each other as peers.<\/p>\n\n\n\n<p>Each ESP32 has a <a href=\"https:\/\/randomnerdtutorials.com\/get-change-esp32-esp8266-mac-address-arduino\/\">unique MAC Address<\/a> and that&#8217;s how we identify each board (learn how to <a href=\"https:\/\/randomnerdtutorials.com\/get-change-esp32-esp8266-mac-address-arduino\/\">Get and Change the ESP32 MAC Address<\/a>).<\/p>\n\n\n\n<p>To get your board&#8217;s MAC Address, upload the following code.<\/p>\n\n\n<pre style=\"max-height: 40em; margin-bottom: 20px;\"><code class=\"language-c\">\/*\n  Rui Santos &amp; Sara Santos - Random Nerd Tutorials\n  Complete project details at https:\/\/RandomNerdTutorials.com\/get-change-esp32-esp8266-mac-address-arduino\/\n  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files.  \n  The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n*\/\n#include &lt;WiFi.h&gt;\n#include &lt;esp_wifi.h&gt;\n\nvoid readMacAddress(){\n  uint8_t baseMac[6];\n  esp_err_t ret = esp_wifi_get_mac(WIFI_IF_STA, baseMac);\n  if (ret == ESP_OK) {\n    Serial.printf(&quot;%02x:%02x:%02x:%02x:%02x:%02x\\n&quot;,\n                  baseMac[0], baseMac[1], baseMac[2],\n                  baseMac[3], baseMac[4], baseMac[5]);\n  } else {\n    Serial.println(&quot;Failed to read MAC address&quot;);\n  }\n}\n\nvoid setup(){\n  Serial.begin(115200);\n\n  WiFi.mode(WIFI_STA);\n  WiFi.STA.begin();\n\n  Serial.print(&quot;[DEFAULT] ESP32 Board MAC Address: &quot;);\n  readMacAddress();\n}\n \nvoid loop(){\n\n}\n<\/code><\/pre>\n\t<p style=\"text-align:center\"><a class=\"rntwhite\" href=\"https:\/\/github.com\/RuiSantosdotme\/Random-Nerd-Tutorials\/raw\/master\/Projects\/ESP32\/ESP32_Get_MAC_Address.ino\" target=\"_blank\">View raw code<\/a><\/p>\n\n\n\n<p>After uploading the code, open the Serial Monitor at a baud rate of 115200 and press the ESP32 RST\/EN button. The MAC address should be printed as follows:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" decoding=\"async\" width=\"652\" height=\"421\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/01\/ESP32_MAC_Address_Serial_monitor.jpg?resize=652%2C421&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP-NOW ESP32 Getting Board MAC Address\" class=\"wp-image-93078\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/01\/ESP32_MAC_Address_Serial_monitor.jpg?w=652&amp;quality=100&amp;strip=all&amp;ssl=1 652w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/01\/ESP32_MAC_Address_Serial_monitor.jpg?resize=300%2C194&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 652px) 100vw, 652px\" \/><\/figure><\/div>\n\n\n<p>Save your board MAC address because you&#8217;ll need it in the next ESP-NOW examples.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Project Overview<\/h2>\n\n\n\n<p>The example we&#8217;ll show you is very simple so that you can understand how to encrypt your ESP-NOW messages. The sender will send a structure that contains two random numbers, <span class=\"rnthl rntliteral\">x<\/span> and <span class=\"rnthl rntliteral\">y<\/span>, and a <span class=\"rnthl rntliteral\">counter<\/span> variable (to keep track of the number of sent packets).<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" decoding=\"async\" width=\"1000\" height=\"435\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2022\/09\/ESP-NOW-send-encrypted-messages.png?resize=1000%2C435&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP32 ESP-NOW Encrypted Messages Project Overview\" class=\"wp-image-116575\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2022\/09\/ESP-NOW-send-encrypted-messages.png?w=1000&amp;quality=100&amp;strip=all&amp;ssl=1 1000w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2022\/09\/ESP-NOW-send-encrypted-messages.png?resize=300%2C131&amp;quality=100&amp;strip=all&amp;ssl=1 300w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2022\/09\/ESP-NOW-send-encrypted-messages.png?resize=768%2C334&amp;quality=100&amp;strip=all&amp;ssl=1 768w\" sizes=\"(max-width: 1000px) 100vw, 1000px\" \/><\/figure><\/div>\n\n\n<p>Here are the main steps:<\/p>\n\n\n\n<ol class=\"wp-block-list\"><li>The sender sets its PMK;<\/li><li>The sender adds the receiver as a peer and sets its LMK;<\/li><li>The receiver sets its PMK (should be the same of the receiver);<\/li><li>The receiver adds the sender as a peer and sets its LMK (should be the same as the one set on the sender board);<\/li><li>The sender sends the following structure to the receiver board:<\/li><\/ol>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>typedef struct struct_message {\n    int counter;\n    int x;\n    int y;\n} struct_message;<\/code><\/pre>\n\n\n\n<ol start=\"6\"><li>The receiver gets the message.<\/li><\/ol>\n\n\n\n<h2 class=\"wp-block-heading\">ESP32 Sender Sketch (ESP-NOW Encrypted)<\/h2>\n\n\n\n<p>Here&#8217;s the code for the ESP32 Sender board. Copy the code to your Arduino IDE, but don&#8217;t upload it yet. You need to make a few modifications to make it work for you.<\/p>\n\n\n<pre style=\"max-height: 40em; margin-bottom: 20px;\"><code class=\"language-c\">\/*\r\n  Rui Santos &amp; Sara Santos - Random Nerd Tutorials\r\n  Complete project details at https:\/\/RandomNerdTutorials.com\/esp32-esp-now-encrypted-messages\/\r\n  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files.\r\n  The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\r\n*\/\r\n#include &lt;esp_now.h&gt;\r\n#include &lt;WiFi.h&gt;\r\n\r\n\/\/ REPLACE WITH THE RECEIVER'S MAC Address\r\nuint8_t receiverAddress[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};\r\n\r\n\/\/ PMK and LMK keys\r\nstatic const char* PMK_KEY_STR = &quot;REPLACE_WITH_PMK_KEY&quot;;\r\nstatic const char* LMK_KEY_STR = &quot;REPLACE_WITH_LMK_KEY&quot;;\r\n\r\n\/\/ Structure example to send data\r\n\/\/ Must match the receiver structure\r\ntypedef struct struct_message {\r\n    int counter;\r\n    int x;\r\n    int y;\r\n} struct_message;\r\n\r\n\/\/ Create a struct_message called myData\r\nstruct_message myData;\r\n\r\n\/\/ Counter variable to keep track of number of sent packets\r\nint counter;\r\n\r\n\/\/ Variable to save peerInfo\r\nesp_now_peer_info_t peerInfo;\r\n\r\n\/\/ callback when data is sent\r\nvoid OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) {\r\n  Serial.print(&quot;\\r\\nLast Packet Send Status:\\t&quot;);\r\n  Serial.println(status == ESP_NOW_SEND_SUCCESS ? &quot;Delivery Success&quot; : &quot;Delivery Fail&quot;);\r\n}\r\n \r\nvoid setup() {\r\n  \/\/ Init Serial Monitor\r\n  Serial.begin(115200);\r\n \r\n  \/\/ Set device as a Wi-Fi Station\r\n  WiFi.mode(WIFI_STA);\r\n  \r\n  \/\/ Init ESP-NOW\r\n  if (esp_now_init() != ESP_OK) {\r\n    Serial.println(&quot;There was an error initializing ESP-NOW&quot;);\r\n    return;\r\n  }\r\n  \r\n  \/\/ Set PMK key\r\n  esp_now_set_pmk((uint8_t *)PMK_KEY_STR);\r\n  \r\n  \/\/ Register the receiver board as peer\r\n  memcpy(peerInfo.peer_addr, receiverAddress, 6);\r\n  peerInfo.channel = 0;\r\n  \/\/Set the receiver device LMK key\r\n  for (uint8_t i = 0; i &lt; 16; i++) {\r\n    peerInfo.lmk[i] = LMK_KEY_STR[i];\r\n  }\r\n  \/\/ Set encryption to true\r\n  peerInfo.encrypt = true;\r\n  \r\n  \/\/ Add receiver as peer        \r\n  if (esp_now_add_peer(&amp;peerInfo) != ESP_OK){\r\n    Serial.println(&quot;Failed to add peer&quot;);\r\n    return;\r\n  }\r\n\r\n  \/\/ Once ESPNow is successfully Init, we will register for Send CB to\r\n  \/\/ get the status of transmitted packet\r\n  esp_now_register_send_cb(OnDataSent);\r\n}\r\nvoid loop() {\r\n  static unsigned long lastEventTime = millis();\r\n  static const unsigned long EVENT_INTERVAL_MS = 5000;\r\n  if ((millis() - lastEventTime) &gt; EVENT_INTERVAL_MS) {\r\n    lastEventTime = millis();\r\n    \r\n    \/\/ Set values to send\r\n    myData.counter = counter++;\r\n    myData.x = random(0,50);\r\n    myData.y = random(0,50);\r\n  \r\n    \/\/ Send message via ESP-NOW\r\n    esp_err_t result = esp_now_send(receiverAddress, (uint8_t *) &amp;myData, sizeof(myData));\r\n    if (result == ESP_OK) {\r\n      Serial.println(&quot;Sent with success&quot;);\r\n    }\r\n    else {\r\n      Serial.println(&quot;Error sending the data&quot;);\r\n    }  \r\n  }\r\n}\r\n<\/code><\/pre>\n\t<p style=\"text-align:center\"><a class=\"rntwhite\" href=\"https:\/\/github.com\/RuiSantosdotme\/Random-Nerd-Tutorials\/raw\/master\/Projects\/ESP\/ESP_NOW\/ESP_NOW_Encryption\/ESP32_Sender_Encrypted.ino\" target=\"_blank\">View raw code<\/a><\/p>\n\n\n\n<p>Don&#8217;t forget you need to add the receiver&#8217;s MAC address in the code. In my case, the receiver MAC address is <span class=\"rnthl rntliteral\">30:AE:A4:07:0D:64<\/span>. So, it will look as follows on the code:<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>\/\/ REPLACE WITH THE RECEIVER'S MAC Address\nuint8_t receiverAddress&#091;] = {0x30, 0xAE, 0xA4, 0x07, 0x0D, 0x64};<\/code><\/pre>\n\n\n\n<p>Let&#8217;s take a look at the relevant parts of code that deal with encryption.<\/p>\n\n\n\n<p>Create the PMK and LMK keys for this device on the following lines. It can be made of numbers and letters and the keys are 16 bytes (you can search online for &#8220;online byte counter&#8221; to check the length of your keys).<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>static const char* PMK_KEY_STR = \"REPLACE_WITH_PMK_KEY\";\nstatic const char* LMK_KEY_STR = \"REPLACE_WITH_LMK_KEY\";<\/code><\/pre>\n\n\n\n<p>For example, the key can be something like this <span class=\"rnthl rntliteral\">00XXmkwei\/lpP\u00c7f<\/span>. <\/p>\n\n\n\n<p>The sender and receiver should have the same PMK and LMK keys.<\/p>\n\n\n\n<p>Set the device PMK key using the <span class=\"rnthl rntliteral\">esp_now_set_pmk()<\/span> function as follows:<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>esp_now_set_pmk((uint8_t *)PMK_KEY_STR);<\/code><\/pre>\n\n\n\n<p>The LMK is a property of the peer device, so you must set it when you register a device as peer. You set the LMK as follows:<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>for (uint8_t i = 0; i &lt; 16; i++) {\n   peerInfo.lmk&#091;i] = LMK_KEY_STR&#091;i];\n}<\/code><\/pre>\n\n\n\n<p>You also need to set the <span class=\"rnthl rntliteral\">encrypt<\/span> peer property as <span class=\"rnthl rntliteral\">true<\/span>.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>peerInfo.encrypt = true;<\/code><\/pre>\n\n\n\n<p>And that&#8217;s it. This is all you need to do to encrypt ESP-NOW messages. Now, you can use the ESP-NOW function to exchange data and the messages will be encrypted.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">ESP32 Receiver Sketch (ESP-NOW Encrypted Messages)<\/h2>\n\n\n\n<p>Here&#8217;s the code for the ESP32 Receiver board. Copy the code to your Arduino IDE, but don&#8217;t upload it yet. You need to make a few modifications to make it work for you.<\/p>\n\n\n<pre style=\"max-height: 40em; margin-bottom: 20px;\"><code class=\"language-c\">\/*\r\n  Rui Santos &amp; Sara Santos - Random Nerd Tutorials\r\n  Complete project details at https:\/\/RandomNerdTutorials.com\/esp32-esp-now-encrypted-messages\/\r\n  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files.\r\n  The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\r\n*\/\r\n#include &lt;esp_now.h&gt;\r\n#include &lt;WiFi.h&gt;\r\n\r\n\/\/ REPLACE WITH YOUR MASTER MAC Address\r\nuint8_t masterMacAddress[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};\r\n\r\n\/\/ PMK and LMK keys\r\nstatic const char* PMK_KEY_STR = &quot;REPLACE_WITH_PMK_KEY&quot;;\r\nstatic const char* LMK_KEY_STR = &quot;REPLACE_WITH_LMK_KEY&quot;;\r\n\r\n\/\/ Structure example to send data\r\n\/\/ Must match the sender structure\r\ntypedef struct struct_message {\r\n  int counter; \/\/ must be unique for each sender board\r\n  int x;\r\n  int y;\r\n} struct_message;\r\n\r\n\/\/ Create a struct_message called myData\r\nstruct_message myData;\r\n\r\n\/\/ Function to print MAC address on Serial Monitor\r\nvoid printMAC(const uint8_t * mac_addr){\r\n  char macStr[18];\r\n  snprintf(macStr, sizeof(macStr), &quot;%02x:%02x:%02x:%02x:%02x:%02x&quot;,\r\n           mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);\r\n  Serial.println(macStr);\r\n}\r\n\r\n\/\/ Callback function executed when data is received\r\nvoid OnDataRecv(const uint8_t * mac_addr, const uint8_t *incomingData, int len) {\r\n \r\n  Serial.print(&quot;Packet received from: &quot;);\r\n  printMAC(mac_addr);\r\n  \r\n  memcpy(&amp;myData, incomingData, sizeof(myData));\r\n  Serial.print(&quot;Bytes received: &quot;);\r\n  Serial.println(len);\r\n  Serial.print(&quot;Packet number: &quot;);\r\n  Serial.println(myData.counter);\r\n  Serial.print(&quot;X: &quot;);\r\n  Serial.println(myData.x);\r\n  Serial.print(&quot;Y: &quot;);\r\n  Serial.println(myData.y);\r\n}\r\nvoid setup() {\r\n  \/\/ Init Serial Monitor\r\n  Serial.begin(115200);\r\n \r\n  \/\/ Set device as a Wi-Fi Station\r\n  WiFi.mode(WIFI_STA);\r\n  \r\n  \/\/ Init ESP-NOW\r\n  if (esp_now_init() != ESP_OK) {\r\n    Serial.println(&quot;There was an error initializing ESP-NOW&quot;);\r\n    return;\r\n  }\r\n  \r\n  \/\/ Set the PMK key\r\n  esp_now_set_pmk((uint8_t *)PMK_KEY_STR);\r\n  \r\n  \/\/ Register the master as peer\r\n  esp_now_peer_info_t peerInfo;\r\n  memcpy(peerInfo.peer_addr, masterMacAddress, 6);\r\n  peerInfo.channel = 0;\r\n  \/\/ Setting the master device LMK key\r\n  for (uint8_t i = 0; i &lt; 16; i++) {\r\n    peerInfo.lmk[i] = LMK_KEY_STR[i];\r\n  }\r\n  \/\/ Set encryption to true\r\n  peerInfo.encrypt = true;\r\n  \r\n  \/\/ Add master as peer       \r\n  if (esp_now_add_peer(&amp;peerInfo) != ESP_OK){\r\n    Serial.println(&quot;Failed to add peer&quot;);\r\n    return;\r\n  }\r\n  \r\n  \/\/ Once ESPNow is successfully Init, we will register for recv CB to\r\n  \/\/ get recv packer info\r\n  esp_now_register_recv_cb(esp_now_recv_cb_t(OnDataRecv));\r\n}\r\nvoid loop() {\r\n  \r\n}\r\n<\/code><\/pre>\n\t<p style=\"text-align:center\"><a class=\"rntwhite\" href=\"https:\/\/github.com\/RuiSantosdotme\/Random-Nerd-Tutorials\/raw\/master\/Projects\/ESP\/ESP_NOW\/ESP_NOW_Encryption\/ESP32_Receiver_Encrypted.ino\" target=\"_blank\">View raw code<\/a><\/p>\n\n\n\n<p>You need to add the sender board as a peer. So, you need to know its MAC address. Add the sender MAC address in the following line:<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>uint8_t masterMacAddress&#091;] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};<\/code><\/pre>\n\n\n\n<p>Set the PMK and LMK keys. Should be the same as the other board.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>static const char* PMK_KEY_STR = \"REPLACE_WITH_PMK_KEY\";\nstatic const char* LMK_KEY_STR = \"REPLACE_WITH_LMK_KEY\";<\/code><\/pre>\n\n\n\n<p>Set the device PMK key using the <span class=\"rnthl rntliteral\">esp_now_set_pmk()<\/span> function as follows:<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>esp_now_set_pmk((uint8_t *)PMK_KEY_STR);<\/code><\/pre>\n\n\n\n<p>The LMK is a property of the peer device, so you must set it when you register a device as peer. You set the LMK as follows:<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>for (uint8_t i = 0; i &lt; 16; i++) {\n  peerInfo.lmk&#091;i] = LMK_KEY_STR&#091;i];}<\/code><\/pre>\n\n\n\n<p>You also need to set the <span class=\"rnthl rntliteral\">encrypt<\/span> peer property as <span class=\"rnthl rntliteral\">true<\/span>.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>peerInfo.encrypt = true;<\/code><\/pre>\n\n\n\n<p>And that&#8217;s it, now the receiver board can receiver and decrypt the encrypted messages sent by the sender.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Demonstration<\/h2>\n\n\n\n<p>Upload the codes to the corresponding boards.<\/p>\n\n\n\n<p>Open the Serial Monitor to check what&#8217;s going on. You can use PuTTY to be able to see the messages on both boards simultaneously. <\/p>\n\n\n\n<p>This is what you should get on the receiver board:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"501\" height=\"418\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2022\/09\/ESP-NOW-Receiver-Encrypted-Messages-Received.png?resize=501%2C418&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP-NOW Receiver Encrypted Messages PUTTY\" class=\"wp-image-116565\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2022\/09\/ESP-NOW-Receiver-Encrypted-Messages-Received.png?w=501&amp;quality=100&amp;strip=all&amp;ssl=1 501w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2022\/09\/ESP-NOW-Receiver-Encrypted-Messages-Received.png?resize=300%2C250&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 501px) 100vw, 501px\" \/><\/figure><\/div>\n\n\n<p>On the sender board, you should get &#8220;Delivery Success&#8221; messages.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"601\" height=\"469\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2022\/09\/ESP-NOW-Sender-Encrypted-Messages-Serial-Monitor-Delivery-Success.png?resize=601%2C469&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP-NOW Sender Encrypted Messages Delivery Success Serial Monitor\" class=\"wp-image-116566\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2022\/09\/ESP-NOW-Sender-Encrypted-Messages-Serial-Monitor-Delivery-Success.png?w=601&amp;quality=100&amp;strip=all&amp;ssl=1 601w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2022\/09\/ESP-NOW-Sender-Encrypted-Messages-Serial-Monitor-Delivery-Success.png?resize=300%2C234&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 601px) 100vw, 601px\" \/><\/figure><\/div>\n\n\n<h2 class=\"wp-block-heading\">Wrapping Up<\/h2>\n\n\n\n<p>In this tutorial, you learned how to encrypt ESP-NOW messages using PMK and LMK keys.<\/p>\n\n\n\n<p>I tested the encryption in different scenarios and here are the results:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><strong>Sender and receiver encrypted with same keys<\/strong>: receiver board receives the messages successfully;<\/li><\/ul>\n\n\n\n<ul class=\"wp-block-list\"><li>The sender sends encrypted messages, but the receiver doesn&#8217;t have the keys or has different keys: the receiver doesn&#8217;t get the messages;<\/li><\/ul>\n\n\n\n<ul class=\"wp-block-list\"><li><strong>The receiver has the code for encryption but the sender doesn&#8217;t<\/strong>: the receiver gets the messages anyway. I don&#8217;t think this is the behavior we expected. Since we add the encryption code on both boards, one would expect that if the receiver board got a message that is not encrypted, it would ignore it. But that&#8217;s not what happens. It receives all messages, encrypted and not encrypted. At the moment, there isn&#8217;t a way to know if the received message is encrypted or not, which seems like a limitation at the moment. <\/li><\/ul>\n\n\n\n<p>We hope you found this tutorial useful. We have more ESP-NOW examples you may like:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><a href=\"https:\/\/randomnerdtutorials.com\/esp-now-two-way-communication-esp32\/\">ESP-NOW Two-Way Communication Between ESP32 Boards<\/a><\/li><li><a href=\"https:\/\/randomnerdtutorials.com\/esp-now-one-to-many-esp32-esp8266\/\">ESP-NOW with ESP32: Send Data to Multiple Boards (one-to-many)<\/a><\/li><li><a href=\"https:\/\/randomnerdtutorials.com\/esp-now-many-to-one-esp32\/\">ESP-NOW with ESP32: Receive Data from Multiple Boards (many-to-one)<\/a><\/li><li><a href=\"https:\/\/randomnerdtutorials.com\/esp32-esp-now-wi-fi-web-server\/\">ESP32: ESP-NOW Web Server Sensor Dashboard (ESP-NOW + Wi-Fi)<\/a><\/li><li><a href=\"https:\/\/randomnerdtutorials.com\/esp-now-auto-pairing-esp32-esp8266\/\">ESP-NOW: Auto-pairing for ESP32\/ESP8266 with Bidirectional Communication and Web Server<\/a><\/li><\/ul>\n\n\n\n<p>If you would like to learn more about the ESP32 board and IoT, make sure you take a look at our resources:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><a href=\"https:\/\/randomnerdtutorials.com\/learn-esp32-with-arduino-ide\/\">Learn ESP32 with Arduino IDE<\/a><\/li><li><a href=\"https:\/\/randomnerdtutorials.com\/build-web-servers-esp32-esp8266-ebook\/\">Build Web Servers with ESP32 and ESP8266<\/a><\/li><li><a href=\"https:\/\/randomnerdtutorials.com\/firebase-esp32-esp8266-ebook\/\">Firebase Web App with ESP32 and ESP8266<\/a><\/li><li><a href=\"https:\/\/randomnerdtutorials.com\/projects-esp32\/\">Free ESP32 Projects and Tutorials<\/a><\/li><\/ul>\n\n\n\n<p>Thanks for reading.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this guide, you&#8217;ll learn how to encrypt ESP-NOW messages exchanged between ESP32 boards. ESP-NOW uses the CCMP method for encryption using a Primary Master Key (PMK) and Local Master &#8230; <\/p>\n<p class=\"read-more-container\"><a title=\"ESP32: ESP-NOW Encrypted Messages\" class=\"read-more button\" href=\"https:\/\/randomnerdtutorials.com\/esp32-esp-now-encrypted-messages\/#more-116459\" aria-label=\"Read more about ESP32: ESP-NOW Encrypted Messages\">CONTINUE READING \u00bb<\/a><\/p>\n","protected":false},"author":5,"featured_media":116471,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[276,281,277,299,264],"tags":[],"class_list":["post-116459","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-esp32","category-esp32-project","category-esp32-arduino-ide","category-0-esp32","category-project"],"aioseo_notices":[],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2022\/09\/ESP32-ESP-NOW-Encrypted-Messages.jpg?fit=1280%2C720&quality=100&strip=all&ssl=1","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/posts\/116459","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/users\/5"}],"replies":[{"embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/comments?post=116459"}],"version-history":[{"count":16,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/posts\/116459\/revisions"}],"predecessor-version":[{"id":119597,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/posts\/116459\/revisions\/119597"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/media\/116471"}],"wp:attachment":[{"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/media?parent=116459"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/categories?post=116459"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/tags?post=116459"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}