Александр Гольцман
Пакеты crypto в Go
Пакеты из семейства crypto
в языке программирования Go (или Golang) предоставляют обширный набор инструментов для шифрования, хеширования, подписей, а также работы с TLS и криптографически стойкими случайными числами. Это ключевые компоненты при создании безопасных веб-приложений, реализации протоколов шифрования и защите данных.
В этой статье я расскажу, какие возможности предоставляет пакет crypto
, как он устроен и почему он так важен для надёжных и безопасных систем.
Обзор пакетов crypto
Стандартная библиотека Go содержит несколько пакетов для разных криптографических задач. Смотрите, как они делятся по функционалу:
- Хеширование:
crypto/md5
,crypto/sha1
,crypto/sha256
,crypto/sha512
— для вычисления хеш-сумм.crypto/hmac
— для HMAC-подписей, которые гарантируют целостность и аутентификацию данных.
- Шифрование:
crypto/aes
— симметричное шифрование по стандарту AES.crypto/des
— шифрование по алгоритму DES (менее безопасно и редко используется).
- Асимметричная криптография:
crypto/rsa
— работа с ключами RSA для шифрования и цифровых подписей.crypto/ecdsa
— поддержка эллиптических кривых.
- Генерация случайных чисел:
crypto/rand
— получение криптографически стойких случайных байтов.
- TLS-соединения:
crypto/tls
— реализация TLS-протокола, используемая в HTTPS и других защищённых соединениях.
Пакеты crypto
соответствуют современным стандартам шифрования и регулярно обновляются, чтобы оставаться актуальными в сфере информационной безопасности.
Хеширование данных
Хеш-функции создают "отпечаток" (hash) исходного сообщения. Хеш помогает быстро сверять данные и гарантировать их неизменность.
- SHA-256, SHA-512 — надёжные алгоритмы хеширования для контрольных сумм.
- MD5, SHA-1 — устаревшие алгоритмы, используйте их только в нетребовательных задачах, так как они уязвимы к коллизиям.
Покажу на примере, как вычислить SHA-256 хеш строки:
package main
import (
"crypto/sha256"
"fmt"
)
func main() {
data := []byte("Hello, Golang!")
hash := sha256.Sum256(data)
fmt.Printf("%x\n", hash)
}
Здесь я размещаю строку в data
, а sha256.Sum256
возвращает массив байтов, представляющий хеш.
HMAC для целостности и аутентификации
HMAC (Hash-based Message Authentication Code) позволяет проверять, не были ли изменены данные при передаче. Смотрите, как создать HMAC на основе SHA-256:
package main
import (
"crypto/hmac"
"crypto/sha256"
"fmt"
)
func main() {
key := []byte("secret-key")
message := []byte("Hello, HMAC!")
h := hmac.New(sha256.New, key)
h.Write(message)
signature := h.Sum(nil)
fmt.Printf("%x\n", signature)
}
При проверке HMAC вы вычисляете подпись на другой стороне и сверяете её с полученной, что гарантирует целостность и аутентификацию данных.
Симметричное шифрование AES
Алгоритм AES считается одним из самых надёжных. В Go он реализован в пакете crypto/aes
. Симметричное шифрование использует один ключ для шифрования и расшифрования.
Пример шифрования данных:
package main
import (
"crypto/aes"
"crypto/cipher"
"fmt"
)
func main() {
key := []byte("examplekey123456") // 16, 24 или 32 байта
block, err := aes.NewCipher(key)
if err != nil {
panic(err)
}
plaintext := []byte("Hello, AES!")
ciphertext := make([]byte, len(plaintext))
// ECB-режим в Go не встроен, но для примера
// показываю блоковое шифрование без режима.
block.Encrypt(ciphertext, plaintext)
fmt.Printf("Зашифрованный текст: %x\n", ciphertext)
}
На практике стоит использовать режимы шифрования (CBC, GCM), чтобы обеспечить безопасность (например, crypto/cipher.NewGCM
).
Асимметричная криптография (RSA)
Асимметричное шифрование и цифровые подписи позволяют использовать пару ключей: публичный и приватный. В Go для этого есть пакет crypto/rsa
.
privateKey, err := rsa.GenerateKey(rand.Reader, 2048)
if err != nil {
panic(err)
}
publicKey := &privateKey.PublicKey
Далее можно зашифровать сообщение публичным ключом и расшифровать приватным, либо использовать RSA для цифровых подписей. Асимметричная криптография надёжна, но медленнее симметричной.
TLS-соединения
Веб-приложения и микросервисы часто используют HTTPS. Пакет crypto/tls
позволяет создавать защищённые соединения.
srv := &http.Server{
Addr: ":443",
Handler: myHandler,
TLSConfig: &tls.Config{
// настройки TLS
},
}
srv.ListenAndServeTLS("cert.pem", "key.pem")
Смотрите, здесь я разместил пример HTTPS-сервера. Он требует сертификата cert.pem
и приватного ключа key.pem
, которые можно сгенерировать с помощью OpenSSL.
Генерация случайных чисел
Для криптографии нужны стойкие случайные значения. В Go их предоставляет crypto/rand
.
package main
import (
"crypto/rand"
"fmt"
"math/big"
)
func main() {
n, _ := rand.Int(rand.Reader, big.NewInt(100))
fmt.Println("Случайное число:", n)
}
crypto/rand
генерирует действительно случайные байты, в отличие от math/rand
, который выдаёт псевдослучайные числа.
Заключение
Пакеты crypto
в Go предоставляют комплексный набор инструментов для обеспечения безопасности: хеширование, шифрование, цифровые подписи, работа с TLS и генерация криптографически стойких случайных чисел.
Смотрите, что важно учесть:
- Используйте SHA-256, SHA-512 и HMAC для проверки целостности данных.
- Применяйте AES для симметричного шифрования, а RSA — для асимметричного.
- При работе с HTTPS и защищёнными соединениями используйте TLS.
- Генерируйте случайные числа с помощью
crypto/rand
.
Эти пакеты позволяют создавать надёжные и безопасные приложения, защищая данные от подделки, перехвата и несанкционированного доступа.