Друкарня від WE.UA

Криптографія у Python. Частина 2. Що таке підписи HMAC та CMAC?

Зміст

Всіх вітаю! У другій частині про криптографію ми поговоримо про підписи HMAC та CMAC, їх визначення, принцип роботи, відмінності та призначення. Крім того, ми розглянемо їх створення у Python за допомогою тієї самої бібліотеки cryptography.

Теорія

Що таке HMAC?

HMAC — це підпис на основі хешу, завдяки якому ми можемо підтвердити, що, наприклад, надіслане повідомлення незмінювалося та справді було написано тобою. Людина, яка не має ключа не зможе підробити цей підпис. Тобто посилання та ключ піддаються хешуванню, а потім цей хеш передається отримувачу разом із зашифрованим повідомленням. Отримувач робить теж саме хешування та порівнює свій хеш (підпис) із тим, який йому надав відправник.

Що таке CMAC?

CMAC — це підпис, який на відміну від HMAC базується на так званому блоковому шифрі. Цей підпис так само визначає незмінність та те, що повідомлення написане саме тобою, але процес визначення є дещо іншим. Повідомлення спочатку розбивається на блоки завдяки CMAC, а потім блоковий шифр визначає підпис останннього блоку.

Пропоную повернутися до нашої історії. У ній ми одразу пояснюємо і суть HMAC, і суть CMAC, бо вони мають схоже призначення.

Отже, Джош та Патрік працюють в одній компанії, де є багато різних відділів і у кожного відділу є свій унікальний підпис за яким можна зрозуміти, з якого відділу є той чи інший звіт. Джош займається підписанням звітів. Він працює у інженерному віддлі, тому всі підписані ним звіти мають одну й ту саму тематику — інженерія.

Тепер перейдемо до роботи Патріка. На сайті є різні тематики для звітів, тому Патріку необхідно зрозуміти від кого саме звіт і опублікувати його саме під конкретною тематикою. Тут у гру і вступає той самий підпис, який Джош ставить на звіті. Завдяки унікальному підпису Джоша, Патрік одразу розуміє, що цей звіт саме з інженерного відділу і отриманий саме від Джоша, тому його слід опублікувати у тематиці “Інженерія”. Таким чином підпис підтверджує, що та чи інша інформація була надіслана саме від конкретної особи.

Відмінність між хешуванням та шифруванням

Так як HMAC заснований на хешуванні, а CMAC на шифруванні, то слід зрозуміти різницю між процесом хешування та шифрування.

Хешування — це коли ми перетворюємо деякий рядок у набір послідовностей, але це не можна називати шифруванням, бо хеш ми використовуємо для зберігання паролів.

Шифрування — це коли ми перетворюємо деякий рядок у зашифрований набір символів, який називається алгоритмом шифрування. Шифрування ми використовуємо для того, щоб приховати інформацію.

Тобто у них різне призначення. Ми хешуємо щось щоб зберегти це, а шифруємо, щоб приховати щось.

Приклад підписів у коді

Головна відмінність між HMAC та CMAC

Для початку розглянемо головну відмінність між HMAC та CMAC. Справа у тому, що під час створення HMAC ми серед параметрів цього підпису зазначили саме алгоритм хешування, бо HMAC якраз-таки базується на хешуванні. Це можна побачити у цьому рядку:

hmac_creation = hmac.HMAC(secret_key, hashes.SHA256())

SHA256() — це якраз і є алгоритм хешування.

При створенні CMAC ми ж вказали саме алгоритм шифрування. Так як це різні речі, тому тут і постає різниця між цими підписами. Це можна побачити у цьому рядку:

cmac_creation = cmac.CMAC(algorithms.AES(key))

Тут AES() — це і є саме алгоритм шифрування.

Реалізація HMAC у коді

Тепер наведемо реалізацію HMAC у коді за допомогою все тієї ж бібліотеки cryptography. Спершу імпортуємо HMAC та хеш, так як HMAC побудований на основі хешу та модуль os для генерації ключа:

from cryptography.hazmat.primitives import hashes, hmac

Створюємо змінні secret_key(генеруємо випадковий 32 байтний ключ за допомогою функції urandom()) та message для ключа та повідомлення, яке хочемо зашифрувати:

secret_key = os.urandom(32)
message = b"It's HMAC example in Python code!"

Створюємо функцію hmac_authenticator():

def hmac_authenticator(data):

У тілі функції створюємо підпис HMAC, передаючи класу HMAC такі параметри як secret_key (наш ключ) та алгоритм хешування, який будемо використовувати (SHA256):

hmac_creation = hmac.HMAC(secret_key, hashes.SHA256())

Передаємо повідомлення, яке хочемо зашифрувати:

hmac_creation.update(data)

Завершуємо підпис, тобто функція finalize() застосовує параметри нашого HMAC підпису до повідомлення, що підлягає хешуванню:

signature = hmac_creation.finalize()

Також важливою особливістю finalize() є той фактор, що після першого використання об’єкта hmac_creation вона не дозволяє використовуаати чи якось змінювати параметри об’єкта, які ми задали напочатку при створенні підпису.

Повертаємо підпис:

return signature

Викликаємо функцію hmac_authenticator() та передаємо повідомлення (message) як параметр:

print(hmac_authenticator(message))

Ось як виглядає повний код:

from cryptography.hazmat.primitives import hashes, hmac

secret_key = urandom(32)
message = b"It's HMAC example in Python code!"


def hmac_authenticator(data):
    hmac_creation = hmac.HMAC(secret_key, hashes.SHA256())
    hmac_creation.update(data)
    signature = hmac_creation.finalize()

    return signature


print(hmac_authenticator(message))

У результаті ми отримали такий підпис:

b"02\xd8\xae's\x10\x9d\xbc;\xe4\x13gz\xaa\x1f\x8cL\xe4\xef\\\xf9_\xd0\xe3\xa7B\x80^\xa4w\x99"

Ви отримаєте свій підпис, передавши напочатку свій ключ.

Реалізація CMAC у коді

Наступною розглянемо підпис CMAC у коді. Спочатку імпортуємо сам підпис CMAC, функцію algorithms та модуль os:

from cryptography.hazmat.primitives import cmac
from cryptography.hazmat.primitives.ciphers import algorithms
import os

Оголошуємо змінні key (створюємо 16-байтний ключ за допомогою функції urandom()) та message для ключа та повідомлення, яке хочемо зашифрувати:

key = os.urandom(16)
message = b"It's CMAC example in Python code!"

Створюємо функцію cmac_authenticator(), яка приймає дані для шифрування як параметр:

def cmac_authenticator(data):

Створюємо підпис CMAC, вказуємо алгоритм шифрування (AES) та передаємо класу AES наш ключ:

cmac_creation = cmac.CMAC(algorithms.AES(key))

Вказуємо повідомлення (data), яке хочемо зашифрувати:

cmac_creation.update(data)

Завершуємо підпис:

signature = cmac_creation.finalize()

Повертаємо підпис:

return signature

Викликаємо функцію та передаємо їй повідомлення:

print(cmac_authenticator(message))

У результаті отримали такий підпис:

b'\xaf\x0b-~\xa4\x843\x0b\xf8QU\xa8\xc5\xd9\xbb\xde'

Ви отримаєте свій підпис, передавши напочатку свій ключ.

Особливість finalize()

Також важливою особливістю finalize() є той фактор, що після першого використання об’єкта hmac_creation вона не дозволяє використовуаати чи якось змінювати параметри об’єкта, які ми задали напочатку при створенні підпису.

Давайте поглянемо на це у коді:

secret_key = os.urandom(32)
message = b"It's HMAC example in Python code!"


def hmac_authenticator(data):
    hmac_creation = hmac.HMAC(secret_key, hashes.SHA256())
    hmac_creation.update(data)
    signature = hmac_creation.finalize()
    copied_signature = hmac_creation.copy()

    return signature

Тут ми додали функцію copy(), яка копіює наш підпис після його завершення. У результаті отримаємо ось таку помилку через знайому нам особливість finalize():

copied_signature = hmac_creation.copy()
cryptography.exceptions.AlreadyFinalized: Context was already finalized.

Перевірка HMAC підпису

Після реалізації підпису у коді постає питання “А як дізнатися, що цей підпис є правильним?“ — для цього ми використовуємо функцію verify(), але перед цим треба скопіювати сам підпис, бо функція finalize() не дає користуватися ним.

Для перевірки дещо оновлюємо код, додаючи цей рядок:

hmac_creation.verify(b"qwerty")

Тут ми перевіряємо, чи є даний підпис правильним для нашого зашифрованого повідомлення, передавши підпис, який хочемо перевірити у verify(). Ось приклад повного коду:

secret_key = os.urandom(32)
message = b"It's HMAC example in Python code!"


def hmac_authenticator_verification(data):
    hmac_creation = hmac.HMAC(secret_key, hashes.SHA256())
    hmac_creation.update(data)
    hmac_creation.verify(b"qwerty")


print(hmac_authenticator_verification(message))
hmac_creation.verify(b"qwerty")
cryptography.exceptions.InvalidSignature: Signature did not match digest.

Перевірка CMAC підпису

Для перевірки CMAC підпису діє той самий принцип, що й з HMAC. Ось тут повний код для перевірки CMAC підпису:

key = os.urandom(16)
message = b"It's CMAC example in Python code!"


def cmac_authenticator(data):
    cmac_creation = cmac.CMAC(algorithms.AES(key))
    cmac_creation.update(data)
    cmac_creation.verify(b"qwerty")


print(cmac_authenticator(message))
cmac_creation.verify(b"qwerty")
cryptography.exceptions.InvalidSignature: Signature did not match digest.

Висновок

У другій частині статті ми дізналися, що таке підписи HMAC і CMAC, їх суть, відмінність та розглянули практичну реалізацію цих технологій у коді. Дякую за увагу!

Статті про вітчизняний бізнес та цікавих людей:

  • Шлейф сучасного смартфону та його призначення

    Шлейф - це тонка пластикова стрічка з ледь видимими доріжками і саме вона зʼєднує важливі компоненти мобільного, без яких він не запрацює. Власники пристроїв Xiaomi, які стикаються з потребою заміни цієї деталі, можуть підібрати відповідний варіант на сайті AKS.UA

    Теми цього довгочиту:

    Шлейф Для Мобільного
  • Чохли для iPhone 15: повний гід по кольорах, матеріалах і виробниках

    Перед тим як вибрати чохли для iPhone 15, варто визначитися, що саме ви хочете отримати від аксесуара. Комусь потрібен тонкий прозорий корпус, інший покупець шукає посилений захист, а для когось вирішальним стане колір або підтримка MagSafe

    Теми цього довгочиту:

    Чохли Для Iphone
  • Як побудована програма Meest China Academy

    Курс про товарний бізнес охоплює різні етапи роботи: від пошуку ідеї до перевірки товару, логістики та масштабування. Програма Meest China Academy містить 17 модулів, які послідовно розкривають ці теми без зведення всього навчання до однієї універсальної поради.

    Теми цього довгочиту:

    Meest
  • Які технології використані в Айфон 17

    Айфон 17 поєднує OLED-дисплей із частотою до 120 Гц, чип A19, дві камери Fusion 48 Мп і швидке заряджання через USB-C. У COMFY можна купити Айфон 17 з накопичувачем на 256 або 512 ГБ, вибравши конфігурацію відповідно до обсягу фото, відео та застосунків

    Теми цього довгочиту:

    Iphone 17
  • Як вибрати вживаний iPhone: коротке керівництво для розумної покупки

    Вторинний ринок смартфонів Apple активно зростає, і питання, як вибрати вживаний iPhone, стає актуальним для дедалі більшої кількості користувачів. Правильний підхід дозволяє отримати бу iPhone з актуальною iOS і доброю камерою за помітно нижчу ціну, ніж у нових пристроїв.

    Теми цього довгочиту:

    Iphone
Поділись своїми ідеями в новій публікації.
Ми чекаємо саме на твій довгочит!
Magnifique numérique
Magnifique numérique@magnifiquedigitalworld

Прекрасний цифровий світ

93Довгочити
1.9KПерегляди
27Підписники
Підтримати
На Друкарні з 14 липня 2025

Більше від автора

  • Метод zfill() у Python

    У цій статті ми розберемо метод zfill() у Python на основі практичних прикладів його використання.

    Теми цього довгочиту:

    It
  • Команда WHERE у SQL

    Сьогодні ми розглянемо команду WHERE та принцип роботи цієї команди.

    Теми цього довгочиту:

    Програмування
  • Робота з омогліфами у Python

    У цій статті ми розберемо бібліотеку confusables та її функціонал. Також ми розглянемо, що таке омогліфи та як їх використовують.

    Теми цього довгочиту:

    Програмування

Це також може зацікавити:

  • Java. Основи неблокуючого I/O

    epoll - це механізм введення-виведення, який дозволяє ефективно моніторити кілька файлових дескрипторів

    Теми цього довгочиту:

    Java
  • Відпустити важче, ніж здається: чому підлітку варто дати право вибору

    Ми всі хочемо, щоб наші діти виросли самостійними. Ми повторюємо це собі й іншим батькам на кожному кутку: «головне — щоб він навчився приймати рішення сам», «хочу, щоб вона вміла обирати». А потім настає момент, коли дитина справді хоче обирати сама — і тут починаються проблеми.

    AI ! Публікація містить зображення, або фрагменти тексту, створені за допомогою штучного інтелекту

    Теми цього довгочиту:

    Підлітки
  • Світ став занадто складний… через Google. Отримання коду в смс.

    Це буде першою із серії статей які мають на меті дві цілі: показати складність сучасного світу програмування, та розважити майже всіх читачів, хто не має відношення до розробки на Android, хто має відношення - вибачайте, вас очікує масивний жопний біль.

    Теми цього довгочиту:

    Android

Коментарі (0)

Підтримайте автора першим.
Напишіть коментар!

Це також може зацікавити:

  • Java. Основи неблокуючого I/O

    epoll - це механізм введення-виведення, який дозволяє ефективно моніторити кілька файлових дескрипторів

    Теми цього довгочиту:

    Java
  • Відпустити важче, ніж здається: чому підлітку варто дати право вибору

    Ми всі хочемо, щоб наші діти виросли самостійними. Ми повторюємо це собі й іншим батькам на кожному кутку: «головне — щоб він навчився приймати рішення сам», «хочу, щоб вона вміла обирати». А потім настає момент, коли дитина справді хоче обирати сама — і тут починаються проблеми.

    AI ! Публікація містить зображення, або фрагменти тексту, створені за допомогою штучного інтелекту

    Теми цього довгочиту:

    Підлітки
  • Світ став занадто складний… через Google. Отримання коду в смс.

    Це буде першою із серії статей які мають на меті дві цілі: показати складність сучасного світу програмування, та розважити майже всіх читачів, хто не має відношення до розробки на Android, хто має відношення - вибачайте, вас очікує масивний жопний біль.

    Теми цього довгочиту:

    Android