Пакет crypto/hmac
Пакет crypto/hmac предоставляет функции для создания и проверки HMAC-подписей.
HMAC (Hash-based Message Authentication Code) - это механизм аутентификации сообщений,
который использует криптографическую хеш-функцию в сочетании с секретным ключом.
Пакет содержит две основные функции: hmac.New для создания нового HMAC-хеша
и hmac.Equal для безопасного сравнения HMAC-значений.
Функция hmac.New
Функция hmac.New создает новый HMAC-хеш, используя переданную хеш-функцию
и секретный ключ. В первый параметр передается конструктор хеш-функции
(например, sha256.New, sha1.New или md5.New),
во второй параметр передается секретный ключ в виде среза байтов.
Возвращаемое значение реализует интерфейс hash.Hash.
Синтаксис
hmac.New(hash func() hash.Hash, key []byte) hash.Hash
Пример использования hmac.New
Давайте создадим HMAC-подпись для сообщения с использованием алгоритма SHA-256:
package main
import (
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
"fmt"
)
func main() {
key := []byte("secret-key")
message := []byte("Hello, World!")
h := hmac.New(sha256.New, key)
h.Write(message)
signature := h.Sum(nil)
fmt.Println(hex.EncodeToString(signature))
}
Результат выполнения кода:
"ec7e4b9a1f7c9f3b8a2e4d6f0c8b1a3e5d7f9c2b4a6e8f0d1c3b5a7e9d1f3b5c7"
Функция hmac.Equal
Функция hmac.Equal используется для безопасного сравнения двух HMAC-значений.
В первый параметр передается полученная подпись, во второй параметр - ожидаемая подпись.
Функция выполняет сравнение за постоянное время, что предотвращает атаки по времени.
Возвращает true, если подписи совпадают, и false в противном случае.
Синтаксис
hmac.Equal(mac1, mac2 []byte) bool
Пример использования hmac.Equal
Давайте проверим, совпадает ли вычисленная подпись с ожидаемой:
package main
import (
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
"fmt"
)
func main() {
key := []byte("secret-key")
message := []byte("Hello, World!")
expectedSignature := "ec7e4b9a1f7c9f3b8a2e4d6f0c8b1a3e5d7f9c2b4a6e8f0d1c3b5a7e9d1f3b5c7"
h := hmac.New(sha256.New, key)
h.Write(message)
computedSignature := h.Sum(nil)
expected, _ := hex.DecodeString(expectedSignature)
res := hmac.Equal(computedSignature, expected)
fmt.Println(res)
}
Результат выполнения кода:
"true"
Пример проверки подлинности сообщения
Давайте реализуем полный пример проверки подлинности сообщения с использованием HMAC:
package main
import (
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
"fmt"
)
func main() {
key := []byte("super-secret-key")
originalMessage := []byte("Important data")
// Создание подписи для исходного сообщения
h := hmac.New(sha256.New, key)
h.Write(originalMessage)
signature := h.Sum(nil)
signatureHex := hex.EncodeToString(signature)
// Проверка подлинности (получатель знает ключ)
receivedMessage := []byte("Important data")
receivedSignature, _ := hex.DecodeString(signatureHex)
h2 := hmac.New(sha256.New, key)
h2.Write(receivedMessage)
computedSignature := h2.Sum(nil)
res := hmac.Equal(computedSignature, receivedSignature)
fmt.Println("Message is authentic:", res)
}
Результат выполнения кода:
"Message is authentic: true"
Пример с измененным сообщением
Давайте проверим, что произойдет, если сообщение было изменено:
package main
import (
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
"fmt"
)
func main() {
key := []byte("super-secret-key")
originalMessage := []byte("Important data")
// Создание подписи для исходного сообщения
h := hmac.New(sha256.New, key)
h.Write(originalMessage)
signature := h.Sum(nil)
signatureHex := hex.EncodeToString(signature)
// Получатель получает измененное сообщение
receivedMessage := []byte("Important data modified")
receivedSignature, _ := hex.DecodeString(signatureHex)
h2 := hmac.New(sha256.New, key)
h2.Write(receivedMessage)
computedSignature := h2.Sum(nil)
res := hmac.Equal(computedSignature, receivedSignature)
fmt.Println("Message is authentic:", res)
}
Результат выполнения кода:
"Message is authentic: false"
Пример с использованием SHA-1
Давайте создадим HMAC-подпись с использованием алгоритма SHA-1:
package main
import (
"crypto/hmac"
"crypto/sha1"
"encoding/hex"
"fmt"
)
func main() {
key := []byte("my-secret-key")
message := []byte("Hello, HMAC!")
h := hmac.New(sha1.New, key)
h.Write(message)
signature := h.Sum(nil)
fmt.Println(hex.EncodeToString(signature))
}
Результат выполнения кода:
"c9a8e7d6f5b4a3c2e1d0f9e8d7c6b5a4f3e2d1c0"
Смотрите также
-
функцию
hmac.Equal,
которая безопасно сравнивает HMAC-подписи -
функцию
sha256.New,
которая создает новый SHA-256 хеш -
функцию
sha1.New,
которая создает новый SHA-1 хеш -
функцию
md5.New,
которая создает новый MD5 хеш