Интерфейс cipher.BlockMode
Интерфейс cipher.BlockMode из пакета crypto/cipher определяет поведение блочных режимов шифрования. Он предоставляет методы для шифрования и дешифрования данных по блокам с использованием алгоритмов блочного шифрования, таких как AES или DES. Интерфейс содержит два метода: BlockSize, который возвращает размер блока в байтах, и CryptBlocks, который выполняет шифрование или дешифрование данных.
Синтаксис
type BlockMode interface {
BlockSize() int
CryptBlocks(dst, src []byte)
}
Интерфейс BlockMode реализуется различными режимами шифрования, такими как CBC (Cipher Block Chaining), CFB (Cipher Feedback) и другими. Метод BlockSize возвращает размер блока шифра в байтах, а метод CryptBlocks шифрует или дешифрует данные, переданные в слайсе src, и записывает результат в слайс dst.
Пример использования CBC режима для шифрования
Давайте рассмотрим пример шифрования данных с использованием режима CBC (Cipher Block Chaining) и алгоритма AES:
package main
import (
"crypto/aes"
"crypto/cipher"
"crypto/rand"
"fmt"
"io"
)
func main() {
key := []byte("examplekey123456") // 16 bytes for AES-128
plaintext := []byte("hello world 12345")
block, err := aes.NewCipher(key)
if err != nil {
panic(err)
}
ciphertext := make([]byte, aes.BlockSize+len(plaintext))
iv := ciphertext[:aes.BlockSize]
if _, err := io.ReadFull(rand.Reader, iv); err != nil {
panic(err)
}
mode := cipher.NewCBCEncrypter(block, iv)
mode.CryptBlocks(ciphertext[aes.BlockSize:], plaintext)
fmt.Printf("%x\n", ciphertext)
}
Результат выполнения кода (пример вывода):
"c8b5f7a3d1e9c2b4a6d8f0e1c3d5e7f9a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6"
В этом примере мы создаем новый шифр AES, генерируем случайный вектор инициализации (IV) и создаем объект BlockMode с помощью функции cipher.NewCBCEncrypter. Метод CryptBlocks шифрует данные, записывая результат в слайс ciphertext.
Пример использования CBC режима для дешифрования
Теперь рассмотрим пример дешифрования данных, зашифрованных в предыдущем примере:
package main
import (
"crypto/aes"
"crypto/cipher"
"fmt"
)
func main() {
key := []byte("examplekey123456") // 16 bytes for AES-128
ciphertext, _ := hex.DecodeString("c8b5f7a3d1e9c2b4a6d8f0e1c3d5e7f9a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6")
block, err := aes.NewCipher(key)
if err != nil {
panic(err)
}
iv := ciphertext[:aes.BlockSize]
ciphertext = ciphertext[aes.BlockSize:]
mode := cipher.NewCBCDecrypter(block, iv)
mode.CryptBlocks(ciphertext, ciphertext)
fmt.Printf("%s\n", ciphertext)
}
Результат выполнения кода:
"hello world 12345"
Здесь мы используем функцию cipher.NewCBCDecrypter для создания дешифратора с тем же ключом и вектором инициализации. Метод CryptBlocks дешифрует данные, записывая результат обратно в слайс ciphertext.
Важные особенности
При использовании интерфейса BlockMode важно помнить, что данные должны быть выровнены по размеру блока шифра. Для режима CBC требуется, чтобы длина входных данных была кратна размеру блока, иначе необходимо использовать дополнение (padding). Также стоит учитывать, что метод CryptBlocks изменяет переданные слайсы, поэтому для сохранения исходных данных необходимо создать копию.
Смотрите также
-
функцию
cipher.NewCBCEncrypter,
которая создает шифратор CBC -
функцию
cipher.NewCBCDecrypter,
которая создает дешифратор CBC -
интерфейс
cipher.Block,
который представляет собой блочный шифр -
интерфейс
cipher.Stream,
который используется для поточного шифрования