HMAC-SHA256 для целостности сообщений
Создавайте и проверяйте подписи HMAC-SHA256, чтобы гарантировать целостность данных API.
«HMAC-SHA256 для целостности сообщений» — бесплатный урок Java Academy на CoddyKit. Это урок 3 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Java Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Java Academy содержит 4 уроков всего.
Что такое HMAC
HMAC (код аутентификации сообщения на основе хеша) объединяет криптографическую хеш-функцию с секретным ключом и создаёт MAC. Он доказывает, что данные не были изменены и что отправитель знает секретный ключ.
HMAC и обычный хеш
Обычный хеш SHA-256 может вычислить любой. Для HMAC требуется секретный ключ — только знающие его стороны могут создать или проверить корректный HMAC. Обычные хеши обеспечивают целостность, но не аутентификацию.
Вычисление HMAC-SHA256 в Java
Используйте Mac.getInstance("HmacSHA256"), инициализируйте его с помощью SecretKeySpec и вызовите doFinal(data).
byte[] keyBytes = "my-secret-key".getBytes(StandardCharsets.UTF_8);
SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "HmacSHA256");
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(keySpec);
byte[] hmac = mac.doFinal("payload data".getBytes(StandardCharsets.UTF_8));
String hmacHex = HexFormat.of().formatHex(hmac);
System.out.println(hmacHex); // 64-char hexПроверка HMAC
Повторно вычислите HMAC для полученных данных с помощью общего ключа. Для предотвращения атак по времени выполнения используйте сравнение за постоянное время (MessageDigest.isEqual).
byte[] expectedHmac = computeHmac(key, receivedPayload);
byte[] actualHmac = HexFormat.of().parseHex(receivedHmacHex);
boolean valid = MessageDigest.isEqual(expectedHmac, actualHmac);
if (!valid) throw new SecurityException("HMAC verification failed — data tampered!");Генерация безопасного ключа
Ключи HMAC должны состоять из случайных байтов, а не из паролей. Используйте KeyGenerator или SecureRandom, чтобы сгенерировать 256-битный ключ.
KeyGenerator kg = KeyGenerator.getInstance("HmacSHA256");
kg.init(256);
SecretKey key = kg.generateKey();
String b64Key = Base64.getEncoder().encodeToString(key.getEncoded());Подписание запросов API с помощью HMAC
Вычисляйте HMAC для HTTP-метода, пути, временной отметки и тела запроса. Включайте HMAC в заголовок X-Signature. Сервер повторно вычисляет HMAC и сравнивает результаты, чтобы проверить, что запрос не был изменён.
String payload = method + "\n" + path + "\n" + timestamp + "\n" + body;
byte[] hmac = computeHmac(apiSecretKey, payload);
request.header("X-Signature", "hmac-sha256=" + HexFormat.of().formatHex(hmac));
request.header("X-Timestamp", timestamp);Защита от атак повторного воспроизведения
Злоумышленник может повторно отправить корректно подписанный запрос. Включайте временную отметку в подписываемые данные и отклоняйте запросы, созданные несколько минут назад или раньше.
long timestamp = Long.parseLong(request.getHeader("X-Timestamp"));
if (Math.abs(System.currentTimeMillis() / 1000 - timestamp) > 300) {
throw new SecurityException("Request too old — possible replay attack");
}Проверка вебхуков с помощью HMAC
GitHub, Stripe и многие другие сервисы подписывают вебхуки с помощью HMAC. Проверяйте заголовок X-Hub-Signature-256, чтобы убедиться, что вебхук пришёл от сервиса и не был изменён.
// GitHub webhook verification:
String received = request.getHeader("X-Hub-Signature-256").replace("sha256=","");
byte[] expected = computeHmac(webhookSecret, request.getBody());
boolean valid = MessageDigest.isEqual(expected, HexFormat.of().parseHex(received));HMAC в JWT
HS256 (HMAC-SHA256) — распространённый алгоритм подписи JWT. Заголовок и полезная нагрузка подписываются общим секретом. И издатель, и проверяющая сторона должны знать секрет — это подходит для микросервисов в одной доверенной области.
Ротация ключей HMAC
Периодически меняйте ключи HMAC. Во время смены в течение короткого переходного периода принимайте HMAC, созданные как старым, так и новым ключом, а затем выведите старый ключ из использования.
Когда использовать HMAC, а когда цифровые подписи
HMAC: симметричный механизм — обе стороны используют общий секрет, он работает быстро и подходит для внутренних API и проверки вебхуков. Цифровые подписи (RSA/ECDSA): асимметричный механизм — только подписывающая сторона имеет закрытый ключ, а проверить подпись может любой обладатель открытого ключа; это подходит для JWT в распределённых системах.
Быстрая проверка
Почему при сравнении HMAC необходимо использовать равенство за постоянное время?
Итоги
HMAC-SHA256 обеспечивает аутентифицированную целостность — подтверждает происхождение данных и отсутствие изменений. Используйте Mac.getInstance("HmacSHA256"). Всегда используйте сравнение за постоянное время. Добавляйте временные отметки для предотвращения атак повторного воспроизведения. Применяйте HMAC для подписания запросов API, проверки вебхуков и JWT с HS256.
Часто задаваемые вопросы
Урок «HMAC-SHA256 для целостности сообщений» бесплатный?
Да — полный текст урока «HMAC-SHA256 для целостности сообщений» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Java Academy, подпишись на CoddyKit PRO. Курс Java Academy содержит 4 уроков всего.
Чему я научусь в уроке «HMAC-SHA256 для целостности сообщений»?
Создавайте и проверяйте подписи HMAC-SHA256, чтобы гарантировать целостность данных API. Ты практикуешь Java Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Java Academy?
Предыдущий опыт не требуется. Java Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 3 из 4.
Сколько времени занимает урок «HMAC-SHA256 для целостности сообщений»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Java Academy?
Да. Каждый урок Java Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Криптографическое хеширование с MessageDigest
- Симметричное шифрование AES
- HMAC-SHA256 для целостности сообщений
- JWT: структура, создание и проверка