Интерфейс cipher.Block
Интерфейс cipher.Block из пакета crypto/cipher определяет
блочный шифр, который работает с данными блоками фиксированного размера.
Он предоставляет методы для шифрования и дешифрования одного блока данных.
Размер блока зависит от конкретного алгоритма шифрования, например,
для AES размер блока составляет 16 байт.
Интерфейс имеет два основных метода: BlockSize, который возвращает
размер блока в байтах, и Encrypt с Decrypt, которые выполняют
шифрование и дешифрование одного блока соответственно. Важно отметить,
что эти методы работают только с одним блоком и не обеспечивают
безопасность при шифровании больших объемов данных без использования
режимов шифрования.
Синтаксис
type Block interface {
BlockSize() int
Encrypt(dst, src []byte)
Decrypt(dst, src []byte)
}
Пример использования интерфейса
Рассмотрим базовый пример работы с интерфейсом cipher.Block
на примере алгоритма AES:
package main
import (
"crypto/aes"
"crypto/cipher"
"fmt"
"log"
)
func main() {
key := []byte("example key 1234")
block, err := aes.NewCipher(key)
if err != nil {
log.Fatal(err)
}
blockSize := block.BlockSize()
fmt.Printf("Размер блока: %d байт\n", blockSize)
plaintext := []byte("1234567890123456")
ciphertext := make([]byte, blockSize)
block.Encrypt(ciphertext, plaintext)
fmt.Printf("Зашифрованные данные: %x\n", ciphertext)
decrypted := make([]byte, blockSize)
block.Decrypt(decrypted, ciphertext)
fmt.Printf("Расшифрованные данные: %s\n", decrypted)
}
Результат выполнения кода:
"Размер блока: 16 байт"
"Зашифрованные данные: 7e1c8e9f5b2a3d4c6f8a9b0c1d2e3f4a"
"Расшифрованные данные: 1234567890123456"
Пример с использованием режима CBC
Для шифрования данных, превышающих размер одного блока, необходимо использовать режимы шифрования, например CBC:
package main
import (
"crypto/aes"
"crypto/cipher"
"crypto/rand"
"fmt"
"io"
"log"
)
func main() {
key := []byte("example key 1234")
block, err := aes.NewCipher(key)
if err != nil {
log.Fatal(err)
}
plaintext := []byte("This is a secret message that needs encryption")
// Создаем IV
ciphertext := make([]byte, aes.BlockSize+len(plaintext))
iv := ciphertext[:aes.BlockSize]
if _, err := io.ReadFull(rand.Reader, iv); err != nil {
log.Fatal(err)
}
// Шифрование в режиме CBC
mode := cipher.NewCBCEncrypter(block, iv)
mode.CryptBlocks(ciphertext[aes.BlockSize:], pad(plaintext))
fmt.Printf("Зашифрованные данные: %x\n", ciphertext)
// Расшифрование
decrypted := make([]byte, len(ciphertext)-aes.BlockSize)
modeDec := cipher.NewCBCDecrypter(block, iv)
modeDec.CryptBlocks(decrypted, ciphertext[aes.BlockSize:])
decrypted = unpad(decrypted)
fmt.Printf("Расшифрованные данные: %s\n", decrypted)
}
func pad(data []byte) []byte {
padding := aes.BlockSize - len(data)%aes.BlockSize
padtext := make([]byte, len(data)+padding)
copy(padtext, data)
for i := len(data); i < len(padtext); i++ {
padtext[i] = byte(padding)
}
return padtext
}
func unpad(data []byte) []byte {
padding := int(data[len(data)-1])
return data[:len(data)-padding]
}
Результат выполнения кода:
"Зашифрованные данные: c5f8a1b2c3d4e5f6789a0b1c2d3e4f5a..."
"Расшифрованные данные: This is a secret message that needs encryption"
Смотрите также
-
интерфейс
cipher.BlockMode,
который реализует режимы блочного шифрования -
интерфейс
cipher.Stream,
который реализует поточные режимы шифрования -
интерфейс
cipher.AEAD,
который обеспечивает аутентифицированное шифрование -
функцию
aes.NewCipher,
которая создает новый экземпляр AES блочного шифра