Jump to content

MDM331AID/Experiment 11

From cognifront

Experiment: Password-Protected Smart Sensor System

Aim

To design and implement a password-protected smart sensor system that allows access to sensor data only after successful authentication, demonstrating basic IoT security concepts.

Objectives

  • To understand the importance of security in IoT systems.
  • To interface a DHT11 temperature and humidity sensor with an ESP32.
  • To connect the ESP32 to a Wi-Fi network.
  • To implement a web server on the ESP32 for accessing sensor data.
  • To implement password-based authentication for protecting sensor data.
  • To use the SHA-256 hashing algorithm for secure password verification.
  • To allow access to sensor data only after successful authentication.
  • To demonstrate access denial when incorrect authentication credentials are provided.

Components Required

Sr. No. Component / Software Quantity
1 ESP32 development board 1
2 DHT11 temperature and humidity sensor 1
3 USB cable 1
4 Patch cords / jumper wires As required
5 Wi-Fi router / hotspot 1
6 Computer or smartphone with a web browser 1
7 Arduino IDE 1
8 DHT sensor library 1
9 ESP32 Arduino core / Wi-Fi library 1

Theory

Internet of Things (IoT) is a technology in which physical devices equipped with sensors, processing units and communication capabilities collect and exchange data over a network. Since IoT devices are often connected to networks, protecting their data and controlling access to the devices are important security requirements.

An IoT security system should ensure that only authorized users can access protected sensor data or device functions. Authentication is the process of verifying the identity of a user or device before granting access to a protected resource.

In this experiment, an ESP32 is connected to a DHT11 temperature and humidity sensor. The ESP32 connects to a Wi-Fi network and operates as a small web server. A user can access the ESP32 using a web browser by entering its IP address.

The sensor data is not displayed immediately. The user must first provide valid authentication credentials. If authentication is successful, the ESP32 provides access to the sensor dashboard. If the credentials are incorrect, access to the sensor data is denied.

The basic operation of the system is:

DHT11 Sensor
      ↓
    ESP32
      ↓
    Wi-Fi
      ↓
  Web Server
      ↓
Authentication
      ↓
 ┌───────────────┐
 │               │
 ↓               ↓
Valid          Invalid
Password       Password
 │               │
 ↓               ↓
Sensor         Access
Data           Denied

Password Authentication

Password authentication is a method of verifying a user's identity by comparing credentials provided by the user with the credentials stored by the system.

A simple implementation could directly compare the entered password with a stored password. However, storing passwords directly is not considered a good security practice.

Instead, this experiment demonstrates password hashing.

SHA-256 Hashing

SHA-256 (Secure Hash Algorithm 256-bit) is a cryptographic hashing algorithm used to convert input data of any length into a fixed-size 256-bit hash.

The output is normally represented as a 64-character hexadecimal value.

Basic characteristics of SHA-256 are:

  • It accepts input data of any length.
  • It always produces a fixed 256-bit output.
  • The output is represented using 64 hexadecimal characters.
  • The same input always produces the same hash.
  • A small change in the input produces a completely different hash.
  • It is designed to be difficult to reverse the hash back to the original input.
  • SHA-256 is a hashing algorithm, not an encryption algorithm.
  • It can be used to verify passwords and detect changes in data.

The basic working process of SHA-256 is:

Input Data
    ↓
Convert into Binary
    ↓
Add Padding
    ↓
Divide into 512-bit Blocks
    ↓
Expand Each Block into 64 Words
    ↓
Initialize Eight 32-bit Registers
    ↓
Perform 64 Rounds of Processing
    ↓
Bitwise Operations and Modular Addition
    ↓
Combine Eight 32-bit Results
    ↓
256-bit Hash
    ↓
64 Hexadecimal Characters

During processing, SHA-256 uses operations such as:

  • XOR – performs bit-by-bit exclusive OR operation.
  • AND – performs bit-by-bit AND operation.
  • NOT – inverts the bits.
  • Bit Rotation – rotates bits to the left or right.
  • Bit Shifting – shifts bits to the left or right.
  • Modular Addition – performs addition using a fixed 32-bit word size.

SHA-256 uses predefined constants and performs 64 processing rounds for each 512-bit block. These operations repeatedly mix the input data to produce the final hash.

For example:

Password
   ↓
admin123
   ↓
SHA-256
   ↓
240be518fabd2724ddb6f04eeb1da5967448d7e831c08c8fa822809f74c720a9

In this experiment, the password entered by the user is converted into a SHA-256 hash. The generated hash is then compared with the stored password hash. If both hashes are the same, the password is considered correct and the user is allowed to access the protected sensor data.

Note: SHA-256 is used in this experiment to demonstrate the basic concept of password hashing. For real-world password storage, password-specific algorithms such as salted Argon2, bcrypt, scrypt or PBKDF2 are preferred.

ESP32 Web Server

The ESP32 contains built-in Wi-Fi capability and can operate as a web server. A web server listens for requests from a client such as a web browser and sends an appropriate response.

In this experiment, the ESP32 provides:

  • Login page: Allows the user to enter authentication credentials.
  • Authentication: Verifies the entered password.
  • Sensor dashboard: Displays temperature and humidity after successful authentication.
  • Access denial: Prevents unauthorized users from accessing the sensor data.

The user can access the system using the IP address assigned to the ESP32.

For example:

http://192.168.1.105

The ESP32 operates in Wi-Fi Station (STA) mode and obtains an IP address from the connected Wi-Fi network. The assigned IP address is displayed in the Serial Monitor and is used to access the ESP32 web server.

Pin Connections

The following connections are used to interface the DHT11 sensor with the ESP32.

DHT11 Pin ESP32 Pin Description
VCC 3.3V Power supply
DATA GPIO 4 Digital temperature and humidity data
GND GND Ground connection

Note: The DATA pin can be connected to another suitable ESP32 GPIO if the corresponding pin number is changed in the program.

Connection Diagram

The DHT11 sensor is connected to the ESP32 according to the pin connection table. The ESP32 connects to the Wi-Fi network and hosts the authentication and sensor-data web pages.

The overall connection is:

        DHT11
     ┌─────────┐
     │         │
VCC ─┤ VCC     │
3.3V │         │
     │ DATA ───────── GPIO 4
GND ─┤ GND     │
     └─────────┘
           │
           ↓
        ESP32
           │
         Wi-Fi
           │
           ↓
      Web Browser

Program

Install the DHT sensor library and the required ESP32 board support package using the Arduino IDE.

The program creates a web server on the ESP32, reads temperature and humidity from the DHT11 and protects the sensor dashboard using password authentication.

#include <WiFi.h>
#include <WebServer.h>
#include <DHT.h>
#include "mbedtls/sha256.h"

#define DHT_PIN 4
#define DHT_TYPE DHT11

DHT dht(DHT_PIN, DHT_TYPE);
WebServer server(80);

/* ==============================
   Wi-Fi Credentials
   ============================== */

const char* ssid = "YOUR_WIFI_NAME";
const char* wifiPassword = "YOUR_WIFI_PASSWORD";

/* ==============================
   Login Credentials
   ============================== */

const char* loginUsername = "admin";

/*
   Password:
   admin123

   SHA-256 hash:
   240be518fabd2724ddb6f04eeb1da5967448d7e831c08c8fa822809f74c720a9
*/

const char* storedPasswordHash =
  "240be518fabd2724ddb6f04eeb1da5967448d7e831c08c8fa822809f74c720a9";

bool authenticated = false;


/* =========================================
   SHA-256 Function
   ========================================= */

String sha256(String input)
{
  unsigned char hash[32];

  mbedtls_sha256_context ctx;

  mbedtls_sha256_init(&ctx);

  /*
     0 = SHA-256
     1 = SHA-224
  */
  mbedtls_sha256_starts(&ctx, 0);

  mbedtls_sha256_update(
    &ctx,
    (const unsigned char*)input.c_str(),
    input.length()
  );

  mbedtls_sha256_finish(&ctx, hash);

  mbedtls_sha256_free(&ctx);

  String result = "";

  for (int i = 0; i < 32; i++)
  {
    if (hash[i] < 0x10)
    {
      result += "0";
    }

    result += String(hash[i], HEX);
  }

  return result;
}


/* =========================================
   Login Page
   ========================================= */

void handleRoot()
{
  String html = "";

  html += "<!DOCTYPE html>";
  html += "<html>";
  html += "<head>";

  html += "<meta name='viewport' ";
  html += "content='width=device-width, initial-scale=1'>";

  html += "<title>Smart Sensor Login</title>";

  html += "<style>";

  html += "body{";
  html += "font-family:Arial;";
  html += "background:#f2f2f2;";
  html += "text-align:center;";
  html += "padding:40px;";
  html += "}";

  html += ".box{";
  html += "max-width:400px;";
  html += "margin:auto;";
  html += "background:white;";
  html += "padding:30px;";
  html += "border-radius:12px;";
  html += "box-shadow:0 4px 15px rgba(0,0,0,0.15);";
  html += "}";

  html += "input{";
  html += "width:90%;";
  html += "padding:12px;";
  html += "margin:8px;";
  html += "border:1px solid #ccc;";
  html += "border-radius:6px;";
  html += "}";

  html += "input[type=submit]{";
  html += "width:96%;";
  html += "background:#1976d2;";
  html += "color:white;";
  html += "border:none;";
  html += "cursor:pointer;";
  html += "}";

  html += "</style>";

  html += "</head>";

  html += "<body>";

  html += "<div class='box'>";

  html += "<h1>Smart Sensor System</h1>";

  html += "<p>Password Protected IoT System</p>";

  html += "<form action='/login' method='POST'>";

  html += "<input type='text' ";
  html += "name='username' ";
  html += "placeholder='Username' required>";

  html += "<br>";

  html += "<input type='password' ";
  html += "name='password' ";
  html += "placeholder='Password' required>";

  html += "<br>";

  html += "<input type='submit' value='Login'>";

  html += "</form>";

  html += "</div>";

  html += "</body>";
  html += "</html>";

  server.send(200, "text/html", html);
}


/* =========================================
   Login Authentication
   ========================================= */

void handleLogin()
{
  String enteredUsername = server.arg("username");
  String enteredPassword = server.arg("password");

  String enteredHash = sha256(enteredPassword);

  Serial.println();
  Serial.println("Login attempt");
  Serial.print("Username: ");
  Serial.println(enteredUsername);

  Serial.print("Password Hash: ");
  Serial.println(enteredHash);

  if (
    enteredUsername == loginUsername &&
    enteredHash == storedPasswordHash
  )
  {
    authenticated = true;

    Serial.println("Authentication successful");

    server.sendHeader("Location", "/sensor");

    server.send(
      302,
      "text/plain",
      "Login successful"
    );
  }
  else
  {
    authenticated = false;

    Serial.println("Authentication failed");

    String html = "";

    html += "<!DOCTYPE html>";
    html += "<html>";
    html += "<head>";

    html += "<meta name='viewport' ";
    html += "content='width=device-width, initial-scale=1'>";

    html += "<title>Access Denied</title>";

    html += "</head>";

    html += "<body style='";
    html += "font-family:Arial;";
    html += "text-align:center;";
    html += "padding:40px;";
    html += "'>";

    html += "<h1>Access Denied</h1>";

    html += "<p>Invalid username or password.</p>";

    html += "<br>";

    html += "<a href='/'>Try Again</a>";

    html += "</body>";
    html += "</html>";

    server.send(
      401,
      "text/html",
      html
    );
  }
}


/* =========================================
   Protected Sensor Page
   ========================================= */

void handleSensor()
{
  if (!authenticated)
  {
    server.sendHeader("Location", "/");

    server.send(
      302,
      "text/plain",
      "Authentication required"
    );

    return;
  }

  float temperature = dht.readTemperature();
  float humidity = dht.readHumidity();

  /*
     Check whether DHT11 reading is valid.
  */

  if (isnan(temperature) || isnan(humidity))
  {
    String html = "";

    html += "<!DOCTYPE html>";
    html += "<html>";

    html += "<body style='";
    html += "font-family:Arial;";
    html += "text-align:center;";
    html += "padding:40px;";
    html += "'>";

    html += "<h1>Sensor Error</h1>";

    html += "<p>Unable to read DHT11 sensor.</p>";

    html += "<a href='/sensor'>Try Again</a>";

    html += "</body>";
    html += "</html>";

    server.send(
      500,
      "text/html",
      html
    );

    return;
  }

  String html = "";

  html += "<!DOCTYPE html>";
  html += "<html>";

  html += "<head>";

  html += "<meta name='viewport' ";
  html += "content='width=device-width, initial-scale=1'>";

  html += "<meta http-equiv='refresh' ";
  html += "content='10'>";

  html += "<title>Sensor Dashboard</title>";

  html += "<style>";

  html += "body{";
  html += "font-family:Arial;";
  html += "background:#f2f2f2;";
  html += "text-align:center;";
  html += "padding:30px;";
  html += "}";

  html += ".box{";
  html += "max-width:500px;";
  html += "margin:auto;";
  html += "background:white;";
  html += "padding:30px;";
  html += "border-radius:12px;";
  html += "box-shadow:0 4px 15px rgba(0,0,0,0.15);";
  html += "}";

  html += ".value{";
  html += "font-size:32px;";
  html += "font-weight:bold;";
  html += "margin:20px;";
  html += "}";

  html += "a{";
  html += "display:inline-block;";
  html += "padding:12px 20px;";
  html += "margin:8px;";
  html += "background:#1976d2;";
  html += "color:white;";
  html += "text-decoration:none;";
  html += "border-radius:6px;";
  html += "}";

  html += ".logout{";
  html += "background:#d32f2f;";
  html += "}";

  html += "</style>";

  html += "</head>";

  html += "<body>";

  html += "<div class='box'>";

  html += "<h1>Smart Sensor System</h1>";

  html += "<h2>Authentication Successful</h2>";

  html += "<p>Temperature</p>";

  html += "<div class='value'>";
  html += String(temperature, 1);
  html += " °C";
  html += "</div>";

  html += "<p>Humidity</p>";

  html += "<div class='value'>";
  html += String(humidity, 1);
  html += " %";
  html += "</div>";

  html += "<p>Data refreshes automatically every 10 seconds.</p>";

  html += "<a href='/sensor'>Refresh</a>";

  html += "<a class='logout' href='/logout'>Logout</a>";

  html += "</div>";

  html += "</body>";
  html += "</html>";

  server.send(
    200,
    "text/html",
    html
  );
}


/* =========================================
   Logout
   ========================================= */

void handleLogout()
{
  authenticated = false;

  Serial.println("User logged out.");

  server.sendHeader(
    "Location",
    "/"
  );

  server.send(
    302,
    "text/plain",
    "Logged out"
  );
}


/* =========================================
   Setup
   ========================================= */

void setup()
{
  Serial.begin(115200);

  delay(1000);

  Serial.println();
  Serial.println("==============================");
  Serial.println("ESP32 Smart Sensor Security");
  Serial.println("==============================");

  /*
     Start DHT11
  */

  dht.begin();

  /*
     Connect to Wi-Fi
  */

  WiFi.mode(WIFI_STA);

  WiFi.begin(
    ssid,
    wifiPassword
  );

  Serial.print("Connecting to Wi-Fi");

  int attempts = 0;

  while (
    WiFi.status() != WL_CONNECTED &&
    attempts < 40
  )
  {
    delay(500);

    Serial.print(".");

    attempts++;
  }

  Serial.println();

  /*
     Check Wi-Fi connection
  */

  if (WiFi.status() != WL_CONNECTED)
  {
    Serial.println("Wi-Fi connection failed.");

    Serial.println(
      "Check SSID and Wi-Fi password."
    );

    return;
  }

  Serial.println("Wi-Fi connected.");

  Serial.print("ESP32 IP address: ");

  Serial.println(WiFi.localIP());

  /*
     Web server routes
  */

  server.on(
    "/",
    HTTP_GET,
    handleRoot
  );

  server.on(
    "/login",
    HTTP_POST,
    handleLogin
  );

  server.on(
    "/sensor",
    HTTP_GET,
    handleSensor
  );

  server.on(
    "/logout",
    HTTP_GET,
    handleLogout
  );

  /*
     Start web server
  */

  server.begin();

  Serial.println("Web server started.");

  Serial.println();
  Serial.println("Open this address in your browser:");

  Serial.print("http://");
  Serial.println(WiFi.localIP());

  Serial.println();

  Serial.println("Username: admin");
  Serial.println("Password: admin123");
}


/* =========================================
   Main Loop
   ========================================= */

void loop()
{
  server.handleClient();
}

Code Explanation

  • WiFi.h: Provides functions required to connect the ESP32 to a Wi-Fi network.
  • WebServer.h: Provides the functionality required to create a web server on the ESP32 and handle HTTP requests.
  • DHT.h: Provides functions for communicating with the DHT11 sensor.
  • mbedtls/sha256.h: Provides the SHA-256 cryptographic hashing functionality available in the ESP32 environment.
  • DHT(): Creates the DHT11 sensor object using the configured GPIO pin and sensor type.
  • WebServer server(80): Creates a web server that listens for HTTP requests on port 80.
  • ssid and wifiPassword: Store the Wi-Fi network name and password required by the ESP32 to connect to the selected Wi-Fi network.
  • WiFi.mode(WIFI_STA): Configures the ESP32 to operate in Station (STA) mode so that it connects to an existing Wi-Fi network.
  • WiFi.begin(): Starts the connection process using the configured Wi-Fi network name and password.
  • WiFi.status(): Checks the current Wi-Fi connection status of the ESP32.
  • WL_CONNECTED: Indicates that the ESP32 has successfully connected to the Wi-Fi network.
  • WiFi.localIP(): Returns the IP address assigned to the ESP32 by the Wi-Fi network.
  • username: Stores the username required for authentication.
  • storedPasswordHash: Stores the SHA-256 hash used for password verification instead of storing the plaintext password.
  • sha256(): Converts the entered password into a SHA-256 hash.
  • handleRoot(): Displays the login page to the user.
  • handleLogin(): Receives the username and password entered by the user and verifies the credentials.
  • server.arg(): Retrieves form data submitted by the browser.
  • authenticated: Stores the current authentication state of the user.
  • handleSensor(): Displays the protected sensor dashboard only when authentication has been successful.
  • dht.readTemperature(): Reads the temperature measured by the DHT11.
  • dht.readHumidity(): Reads the relative humidity measured by the DHT11.
  • handleLogout(): Ends the current authentication state and redirects the user to the login page.
  • WiFi.localIP(): Displays the IP address assigned to the ESP32.
  • server.on(): Associates a URL path with a particular function that handles the request.
  • server.begin(): Starts the ESP32 web server.
  • server.handleClient(): Processes incoming HTTP requests from connected clients.

Authentication Process

The authentication process consists of the following steps:

  1. The user connects the computer or smartphone to the same Wi-Fi network as the ESP32.
  2. The user enters the IP address of the ESP32 into a web browser.
  3. The ESP32 displays the login page.
  4. The user enters the username and password.
  5. The ESP32 receives the submitted credentials.
  6. The entered password is processed using the SHA-256 hashing algorithm.
  7. The resulting hash is compared with the stored password hash.
  8. If both the username and password hash match, authentication is successful.
  9. The ESP32 allows access to the sensor dashboard.
  10. If the credentials do not match, access is denied.
  11. The user can log out to terminate the authenticated state.

Procedure

  1. Connect the DHT11 sensor to the ESP32 according to the pin connection table.
  2. Connect the ESP32 to the computer using a USB cable.
  3. Open the Arduino IDE.
  4. Install the ESP32 board support package if it is not already installed.
  5. Install the DHT sensor library using the Arduino IDE Library Manager.
  6. Enter the Wi-Fi network name and password in the program.
  7. Select the appropriate ESP32 board and COM port.
  8. Compile and upload the program to the ESP32.
  9. Open the Serial Monitor and set the baud rate to 115200.
  10. Wait for the ESP32 to connect to the Wi-Fi network.
  11. Note the IP address displayed in the Serial Monitor.
  12. Connect a computer or smartphone to the same Wi-Fi network.
  13. Open a web browser and enter the ESP32 IP address.
  14. Observe the login page.
  15. Enter an incorrect username or password and observe that access is denied.
  16. Return to the login page and enter the correct credentials.
  17. Observe that the sensor dashboard becomes accessible after successful authentication.
  18. Observe the temperature and humidity values displayed on the dashboard.
  19. Change the environmental conditions around the sensor if required and refresh the dashboard.
  20. Observe the updated sensor readings.
  21. Select the Logout option.
  22. Verify that the system returns to the login page and requires authentication again.

Observations and Output

The following observations can be recorded during the experiment:

Sr. No. Test Condition Expected Result
1 ESP32 connected to Wi-Fi ESP32 obtains an IP address
2 Open ESP32 IP address Login page is displayed
3 Incorrect username Access denied
4 Incorrect password Access denied
5 Correct username and password Authentication successful
6 Access protected sensor page Temperature and humidity are displayed
7 Logout User is returned to login page

An illustrative Serial Monitor output is:

The Serial Monitor displays output similar to the following:

<pre>
==============================
ESP32 Smart Sensor Security
==============================
Connecting to Wi-Fi....
Wi-Fi connected.
ESP32 IP address: 192.168.1.105
Web server started.

Open this address in your browser:
http://192.168.1.105

Username: admin
Password: admin123

Security Considerations

The experiment demonstrates basic authentication and password hashing, but the implementation is intended for educational purposes.

The following security considerations should be understood:

  • Password hashing: The password is converted into a SHA-256 hash before comparison.
  • Authentication: Sensor data is not displayed until valid credentials are provided.
  • Access control: The protected sensor page checks the authentication state before displaying sensor data.
  • Logout: The authentication state is cleared when the user logs out.
  • Network security: The demonstration uses HTTP on a local Wi-Fi network. HTTP does not encrypt network traffic.
  • HTTPS/TLS: A production IoT application should use HTTPS/TLS to protect credentials and sensor data while they are transmitted.
  • Password storage: Production systems should use a properly salted password-hashing scheme rather than relying on a simple stored SHA-256 hash.
  • Session management: A production system should use secure sessions or authentication tokens rather than a simple boolean authentication state.

Result

A password-protected smart sensor system was successfully designed and implemented using an ESP32 and DHT11 sensor. The ESP32 connected to a Wi-Fi network and operated as a web server for providing access to temperature and humidity data.

Password-based authentication was implemented using SHA-256 hashing. Incorrect credentials resulted in access denial, while successful authentication allowed the user to access the protected sensor dashboard.

Thus, the experiment demonstrated basic IoT security concepts including authentication, password hashing and access control for sensor data.

Viva Questions

  1. What is IoT security?
  2. Why is security important in IoT systems?
  3. What is authentication?
  4. What is the difference between authentication and authorization?
  5. What is password hashing?
  6. What is SHA-256?
  7. Why should passwords not be stored directly in plaintext?
  8. What is the purpose of hashing the entered password?
  9. What is the role of the ESP32 web server in this experiment?
  10. What is an HTTP request?
  11. What is the purpose of port 80?
  12. How does the ESP32 obtain its IP address?
  13. What happens when an incorrect password is entered?
  14. What happens after successful authentication?
  15. What is the purpose of the logout operation?
  16. Why is a boolean authentication variable used in this experiment?
  17. Is SHA-256 encryption?
  18. What is the difference between hashing and encryption?
  19. Why is HTTPS preferred over HTTP for real IoT applications?
  20. What is TLS?
  21. Why is the implemented system considered a basic security demonstration rather than a production security system?
  22. What is a salted password hash?
  23. What other security mechanisms can be used in IoT systems?