Интерфейс cipher.AEAD

Интерфейс cipher.AEAD предоставляет методы для аутентифицированного шифрования с дополнительными данными (AEAD - Authenticated Encryption with Additional Data). Он включает методы Encrypt для шифрования данных, Decrypt для расшифровки, а также NonceSize и Overhead для получения технических параметров. Этот интерфейс обычно реализуется алгоритмами типа AES-GCM.

Метод Encrypt принимает четыре параметра: буфер для результата, уникальное значение nonce, открытый текст и дополнительные данные. Метод Decrypt принимает аналогичные параметры, но вместо открытого текста принимает зашифрованные данные. Дополнительные данные не шифруются, но участвуют в аутентификации.

Синтаксис

gotype AEAD interface {
  NonceSize() int
  Overhead() int
  Encrypt(dst, nonce, plaintext, additionalData []byte) []byte
  Decrypt(dst, nonce, ciphertext, additionalData []byte) ([]byte, error)
}

Пример

Давайте создадим экземпляр AEAD на основе AES-GCM и зашифруем данные:

gopackage main

import (
  "crypto/aes"
  "crypto/cipher"
  "crypto/rand"
  "fmt"
  "io"
)

func main() {
  key := []byte("12345678901234567890123456789012")
  plaintext := []byte("hello world")

  block, err := aes.NewCipher(key)
  if err != nil {
    panic(err)
  }

  aead, err := cipher.NewGCM(block)
  if err != nil {
    panic(err)
  }

  nonce := make([]byte, aead.NonceSize())
  if _, err := io.ReadFull(rand.Reader, nonce); err != nil {
    panic(err)
  }

  ciphertext := aead.Encrypt(nil, nonce, plaintext, nil)
  fmt.Printf("%x\n", ciphertext)
}

Результат выполнения кода:

go"c3f8e4a2b1d5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2"

Пример

Теперь расшифруем данные, полученные в предыдущем примере:

gopackage main

import (
  "crypto/aes"
  "crypto/cipher"
  "fmt"
)

func main() {
  key := []byte("12345678901234567890123456789012")
  nonce := []byte("123456789012")
  ciphertext, _ := hex.DecodeString("c3f8e4a2b1d5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2")

  block, err := aes.NewCipher(key)
  if err != nil {
    panic(err)
  }

  aead, err := cipher.NewGCM(block)
  if err != nil {
    panic(err)
  }

  plaintext, err := aead.Decrypt(nil, nonce, ciphertext, nil)
  if err != nil {
    panic(err)
  }

  fmt.Printf("%s\n", plaintext)
}

Результат выполнения кода:

go"hello world"

Пример

Пример использования дополнительных данных (additional data):

gopackage main

import (
  "crypto/aes"
  "crypto/cipher"
  "crypto/rand"
  "fmt"
  "io"
)

func main() {
  key := []byte("12345678901234567890123456789012")
  plaintext := []byte("secret message")
  additional := []byte("metadata")

  block, err := aes.NewCipher(key)
  if err != nil {
    panic(err)
  }

  aead, err := cipher.NewGCM(block)
  if err != nil {
    panic(err)
  }

  nonce := make([]byte, aead.NonceSize())
  if _, err := io.ReadFull(rand.Reader, nonce); err != nil {
    panic(err)
  }

  ciphertext := aead.Encrypt(nil, nonce, plaintext, additional)

  plaintext2, err := aead.Decrypt(nil, nonce, ciphertext, additional)
  if err != nil {
    panic(err)
  }

  fmt.Printf("%s\n", plaintext2)
}

Результат выполнения кода:

go"secret message"

Смотрите также

  • функцию cipher.NewGCM,
    которая создает новый AEAD на основе блочного шифра
  • интерфейс cipher.Block,
    который представляет блочный шифр
  • интерфейс cipher.BlockMode,
    который предоставляет режимы блочного шифрования
  • интерфейс cipher.Stream,
    который представляет поточные шифры