logo
+7 (951) 999-89-94
428003, г. Чебоксары, ул. Федора Гладкова, д.9, оф.319

AES: Работа в режиме Single block

Продолжаем знакомство с AES шифрованием и специализированной библиотекой AESLib и в этой статье подробно разберём работу по шифрованию данных и их расшифровке в т. н. режиме «Single block».

Режим Single block

Режим Single block — это самый простой режим работы по AES шифрования. В этом режиме работа происходит с одиночными (single) блоками по 128 бит, то есть мы можем шифровать отдельные блоки (массивы) по 16 байт и, соответственно, потом их расшифровывать.

Библиотека AESLib поддерживает работу в этом режиме с ключами 128 (16 uint8_t) или 256 бит (32 uint8_t). Ключ для шифрования данных и их расшифровки применяется один и тот же.

В библиотеке AESLib присутствуют две функции для шифрования данных в режиме Single block, они имеют одинаковое устройство, различие заключается только в длине ключа 128 или 256 бит (длина самих шифруемых данных в обоих случаях одинакова — 16 байт).

void aes128_enc_single(const uint8_t* key, void* data);

void aes256_enc_single(const uint8_t* key, void* data);

Библиотека AESLib содержит также соответствующие функции для расшифровки ранее зашифрованных блоков. Устройство этих функций аналогично рассмотренным выше — им в качестве аргументов передаются блок данных и ключ для расшифровки сообщения.

void aes128_dec_single(const uint8_t* key, void* data);

void aes256_dec_single(const uint8_t* key, void* data);

Режим шифрования Single block может использоваться для работы с небольшими объёмами данных, например, его удобно использовать для защиты передаваемых по проводным и беспроводным сетям пакетов. Если ваше сообщение меньше 16-и байт, то его можно дополнить нулями до длины 128 бит (а после расшифровки провести соответствующую операцию по удалению лишних данных).

Рассмотрим теперь пример по AES шифрованию в режиме Single block.

Шифрование в режиме Single block

Обратимся к примеру из нашей предыдущей статьи и подробно разберём AES шифрование блока данных в режиме Single block.

Рассмотрим пример шифрования одиночного блока данных 16 байт (128 бит) с использованием 128-битного ключа.

/*
  AES Single block Encrypt test
*/

#include <AESLib.h>

uint8_t key[] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
byte data[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};

void setup() {
  Serial.begin(115200);
  Serial.println(F("AES Single block Encrypt test start..."));

  Serial.print(F("Data:    "));
  for (byte i = 0; i < 16; i++) {
    Serial.print(data[i]); Serial.print(F(" "));
  }
  Serial.println();
  
  aes128_enc_single(key, data);
  
  Serial.print(F("Encrypt: "));
  for (byte i = 0; i < 16; i++) {
    Serial.print(data[i]); Serial.print(F(" "));
  }
  Serial.println();

}

void loop() {
  
}

Здесь мы вначале подключаем библиотеку AESLib.

#include <AESLib.h>

Затем задаём 16-байтовый ключ шифрования (значение ключа было выбрано произвольно).

uint8_t key[] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};

Далее задаём блок данных (размером 128 бит). Тут значения байтов данных тоже выбраны произвольным образом.

byte data[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};

Выводим на экран (для контроля) содержимое массива data.

  Serial.print(F("Data:    "));
  for (byte i = 0; i < 16; i++) {
    Serial.print(data[i]); Serial.print(F(" "));
  }
  Serial.println();

Шифруем данные по алгоритму AES, передавая функции aes128_enc_single() массивы с данными и ключом шифрования.

  aes128_enc_single(key, data);

Далее выводим на экран результат шифрования.

  Serial.print(F("Encrypt: "));
  for (byte i = 0; i < 16; i++) {
    Serial.print(data[i]); Serial.print(F(" "));
  }
  Serial.println();

И видим, что операция по шифрованию данных прошла успешно. Вот скриншот результата работы нашего скетча:

Шифрование с ключом 256 бит

Теперь немного модифицируем наш скетч для шифрования с ключом 256 бит. Здесь ключ становится длиннее (и более надёжным), а размер блока данных остаётся неизменным — 128 бит (обратите внимание: длина ключа в два раза больше длины шифруемых данных).

Код примера шифрования с ключом 256 бит:

/*
  AES Single block Encrypt 256
*/

#include <AESLib.h>

uint8_t key[] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
byte data[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};

void setup() {
  Serial.begin(115200);
  Serial.println(F("AES Single block Encrypt 256 start..."));

  Serial.print(F("Data:    "));
  for (byte i = 0; i < 16; i++) {
    Serial.print(data[i]); Serial.print(F(" "));
  }
  Serial.println();
  
  aes256_enc_single(key, data);
  
  Serial.print(F("Encrypt: "));
  for (byte i = 0; i < 16; i++) {
    Serial.print(data[i]); Serial.print(F(" "));
  }
  Serial.println();

}

void loop() {
  
}

Здесь мы меняем 16-байтовый ключ шифрования

uint8_t key[] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};

на 32-байтовый (256 бит)

uint8_t key[] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};

и заменяем функцию библиотеки на соответствующую.

  aes256_enc_single(key, data);

Результат работы по шифрованию (неизменного) блока данных

byte data[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};

, разумеется, отличается от предыдущего, что можно увидеть на следующем скриншоте.

Расшифровка в режиме Single block

Теперь давайте разберём расшифровку в режиме Single block ранее зашифрованных блоков данных. В этом примере мы будем работать с одиночными блоками данных по 16 байт (128 бит) с использованием 128-битного ключа.

Код примера:

/*
  AES Single block Decrypt test
*/

#include <AESLib.h>

uint8_t key[] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
byte data[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};

void setup() {
  Serial.begin(115200);
  Serial.println(F("AES Single block Decrypt test start..."));

  Serial.print(F("Data:    "));
  for (byte i = 0; i < 16; i++) {
    Serial.print(data[i]); Serial.print(F(" "));
  }
  Serial.println();
  
  aes128_enc_single(key, data);
  
  Serial.print(F("Encrypt: "));
  for (byte i = 0; i < 16; i++) {
    Serial.print(data[i]); Serial.print(F(" "));
  }
  Serial.println();

  aes128_dec_single(key, data);

  Serial.print(F("Decrypt: "));
  for (byte i = 0; i < 16; i++) {
    Serial.print(data[i]); Serial.print(F(" "));
  }
  Serial.println();
}

void loop() {
  
}

Здесь мы добавляем функцию расшифровки зашифрованных перед этим данных.

  aes128_dec_single(key, data);

И выводим на экран результат расшифровки.

  Serial.print(F("Decrypt: "));
  for (byte i = 0; i < 16; i++) {
    Serial.print(data[i]); Serial.print(F(" "));
  }
  Serial.println();

На скриншоте видно, что результат расшифровки полностью совпадает с исходными данными. Это значит, что наш скетч работает корректно с алгоритмом AES шифрования.

Расшифровка с ключом 256 бит

Модифицируем скетч расшифровки для работы с ключом 256 бит. Ключ становится длиннее, а размер блока данных остаётся неизменным — 128 бит.

Код примера расшифровки с ключом 256 бит:

/*
  AES Single block Decrypt 256
*/

#include <AESLib.h>

uint8_t key[] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
byte data[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};

void setup() {
  Serial.begin(115200);
  Serial.println(F("AES Single block Decrypt 256 start..."));

  Serial.print(F("Data:    "));
  for (byte i = 0; i < 16; i++) {
    Serial.print(data[i]); Serial.print(F(" "));
  }
  Serial.println();
  
  aes256_enc_single(key, data);
  
  Serial.print(F("Encrypt: "));
  for (byte i = 0; i < 16; i++) {
    Serial.print(data[i]); Serial.print(F(" "));
  }
  Serial.println();

  aes256_dec_single(key, data);

  Serial.print(F("Decrypt: "));
  for (byte i = 0; i < 16; i++) {
    Serial.print(data[i]); Serial.print(F(" "));
  }
  Serial.println();
}

void loop() {
  
}

Здесь мы меняем 16-байтовый ключ шифрования (128 бит) на 32-байтовый (256 бит)

uint8_t key[] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};

Заменяем функцию шифрования на соответствующую

  aes256_enc_single(key, data);

и функцию расшифровки тоже на 256-битную.

  aes256_dec_single(key, data);

Результат работы по 256-битному AES шифрованию блока данных можно увидеть на следующем скриншоте.

Как вы видите, всё работает абсолютно корректно и ожидаемо.

Заключение

Сегодня вы освоили практическое шифрование данных по стандарту AES, правда только в самом простом варианте работы в режиме Single block, но в следующих статьях мы продолжим знакомство с этой увлекательной темой и рассмотрим AES шифрование и в других, более продвинутых режимах.

Ссылки по теме

AES: Стандарт шифрования AES

AES: Библиотека AESLib

AES: Работа в режиме Single block

AES: Работа в режиме Multiple blocks