Language: EN

como-usar-sha256-esp32

What is SHA-256 and how to use it on ESP32

In this entry, we will see what SHA-256 is, how it works, and how to use it on an ESP32.

SHA-256 is a secure hashing algorithm that will be very useful when performing tasks such as:

  • Authentication: Validating the identity of devices or users.
  • Secure storage: Protecting passwords and keys on embedded devices.
  • Verifying data integrity: Ensuring that data has not been altered during transmission.

But first, let’s briefly see what SHA-256 is 👇.

What is SHA-256

SHA-256 is a member of the SHA-2 family of hash functions (Secure Hash Algorithm 2) developed by the National Institute of Standards and Technology (NIST).

This hash function takes an input of any length and generates a 256-bit (32-byte) value represented as a 64-digit hexadecimal value.

Main features of SHA-256

  • Output size: 256 bits (32 bytes).
  • Collision resistance: It is computationally infeasible to find two different inputs that produce the same hash.
  • Deterministic: The same input will always produce the same hash.
  • Irreversible: It is not possible to reconstruct the original input from the hash.

The SHA-256 hash is a unique and fixed representation of the original data, meaning that any change in the data will generate a completely different hash.

SHA-256 is a one-way algorithm, which means that it is not possible to obtain the original data from the hash.

This makes it a very useful tool for verifying data integrity and protecting against unauthorized modifications.

Implementing SHA-256 on the ESP32

The ESP32 has a hardware encryption module that includes support for SHA-256. This allows for efficient hashing operations without overloading the CPU.

Let’s see how to implement SHA-256 on the ESP32 using the mbedTLS library.

#include "mbedtls/md.h"
#include "stdlib.h"

void printBlockAsHex(std::vector<uint8_t> data)
{
	for(int i = 0; i < data.size(); i++)
	{
		Serial.printf("%02X ", data[i]);
	}
}

std::vector<uint8_t> generateSHA256(std::string& text)
{
	std::vector<uint8_t> hash(32);

	mbedtls_md_context_t ctx;
	mbedtls_md_type_t md_type = MBEDTLS_MD_SHA256;

	mbedtls_md_init(&ctx);
	mbedtls_md_setup(&ctx, mbedtls_md_info_from_type(md_type), 0);
	mbedtls_md_starts(&ctx);
	mbedtls_md_update(&ctx, (const unsigned char*)text.c_str(), text.length());
	mbedtls_md_finish(&ctx, hash.data());
	mbedtls_md_free(&ctx);

	return hash;
}

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

	std::string message = "www.luisllamas.es";
	auto hash = generateSHA256(message);

	Serial.print(message.c_str());
	Serial.print("\nHash: ");
	printBlockAsHex(hash);
}

void loop() {}
  • input: This is the string we want to hash.
  • input_len: Length of the input string.
  • output: An array of 32 bytes to store the resulting hash.
  • mbedtls_sha256_context: Structure that holds the state of the hash calculation.
  • mbedtls_sha256_init: Initializes the context.
  • mbedtls_sha256_starts: Starts the hash calculation (the second parameter 0 indicates that we are using SHA-256).
  • mbedtls_sha256_update: Processes the input string.
  • mbedtls_sha256_finish: Finishes the calculation and stores the hash in the output buffer.
  • mbedtls_sha256_free: Frees the resources of the context.

When you run it, you will get something like this.

sha256

Practical Examples