Предположим, что разработчик Instagram, WhatsApp или любого другого приложения может видеть ваши сообщения именно в своем хранилище. Все данные, которыми вы когда-либо делились, общались и отправляли. Вы хотите это? Во всем мире сейчас существует тенденция хранить эти данные в зашифрованном виде.

Что такое шифрование?

Шифрование – это способ хранения информации, понятной человеку, в формате, не понятном человеку.

Предположим, вы отправляете сообщение Hello, Bryan! через какой-то инструмент. Этот фрагмент текста зашифровывается перед сохранением в базе данных, поэтому в нем будут храниться некоторые случайные символы, не оставляя следов, что зашифрованный текст может содержать оригинал Hello, Bryan! текст.

Перед экспортом другому пользователю или панели управления эта информация расшифровывается, опять же вне базы данных, оставляя только зашифрованный текст без перезаписи с исходным текстом.

Для этого ключ нужно хранить в тайне, чтобы он не был виден всем. В настоящее время все облачные гиганты предлагают различные системы управления ключами, такие как KMS (Key Management System) для AWS.

Поскольку зачем нужно шифрование, довольно очевидно, давайте перейдем к тому, как мы можем шифровать и расшифровывать в GoLang и PHP.

Примечание. В этой статье будет рассмотрено 256-битное шифрование AES, которое является самым сложным и трудным для взлома [1].

Шифрование и дешифрование в GoLang

TLDR; Полный код доступен как в общих чертах, так и в конце этого раздела.

1. Шифрование

Вам понадобится 32-значный секретный ключ шифрования и 16-значный вектор инициализации, iv:

key := "my32digitkey12345678901234567890"
iv := "my16digitIvKey12"

Подумайте, храните ли вы их как переменные окружения или извлекаете откуда-то, важно, чтобы они не были жестко закодированы.

Для шифрования и дешифрования мы будем использовать встроенный пакет aes. Во-первых, должна быть выполнена инициализация:

block, err := aes.NewCipher([]byte(key))

Обратите внимание, что NewCipher возвращает ошибку в качестве второго параметра [2], поэтому вы можете регистрировать эти ошибки.

Затем создайте массив байтов длины обычного текста и начните шифрование:

mode := cipher.NewCBCEncrypter(block, []byte(iv))
mode.CryptBlocks(ciphertext, plainTextBlock)

преобразовать результат в кодировку Base64:

str := base64.StdEncoding.EncodeToString(ciphertext)

и вуаля, ваш текст теперь зашифрован. Обязательно укажите ошибку в качестве второго возвращаемого параметра на тот случай, если вам нужно ее зарегистрировать. Опять же, полный код (со всеми необходимыми условиями If, с которыми мы столкнулись) доступен ниже в виде GitHub.

2. Расшифровка

Не забудьте свой секрет и ключ iv. Сначала расшифруйте строку:

ciphertext, err := base64.StdEncoding.DecodeString(encrypted)

Снова создайте шифр с помощью aes.NewCipher :

block, err := aes.NewCipher([]byte(key))

и расшифровать его:

mode := cipher.NewCBCDecrypter(block, []byte(iv))
mode.CryptBlocks(ciphertext, ciphertext)
ciphertext = PKCS5UnPadding(ciphertext)

Обратите внимание на функцию PKCS5UnPadding, она дополняет определенный блок данных необходимыми данными для использования в блочном шифре AES.

Результат запуска обеих функций выглядит следующим образом:

Полный код, как показано ниже, также доступен в этой игровой площадке Go:

Шифрование и дешифрование в PHP

TLDR; Полный код доступен в конце этого раздела.

1. Шифрование

Функция для этого в PHP openssl_encrypt. Из своего руководства он шифрует данные (параметр 1) заданным методом (параметр 2), используя ключ и iv (параметры 3 и 5 соответственно) [3]. Параметр 4 определяет, будут ли данные возвращены как есть, OPENSSL_RAW_DATA, или без заполнения, OPENSSL_ZERO_PADDING.

Итак, установите свой ключ и iv:

$key= "my32digitkey12345678901234567890";
$iv = "my16digitIvKey12";

(Обратите внимание, что здесь они жестко закодированы для лучшей визуализации, обычно их нужно хранить в службе управления ключами)

Вызовите openssl_encrypt с его параметрами:

$encrypted = openssl_encrypt(
    $plainText,
    'AES-256-CBC',
    $key,
    0,
    $iv
);
echo "This is encrypted: {$encrypted}\n";

2. Расшифровка

Расшифровка может произойти с openssl_decrypt, который имеет те же 5 первых параметров, что и его противоположность, openssl_encrypt [4]:

$decrypted = openssl_decrypt(
    $encrypted,
    'AES-256-CBC',
    $key,
    0,
    $iv
);
echo "This is a decrypted: {$decrypted}\n";

Результат выглядит следующим образом:

и это то же самое, что написано на GoLang, поэтому вы можете использовать их при преобразовании сохраненных и зашифрованных данных Go в PHP или наоборот.

Опять же, полный код доступен как суть:

Надеюсь, вам понравилось читать! 🤞

Принимайте ваши комментарии и предложения в комментариях 📝.
А также не стесняйтесь обращаться ко мне в LinkedIn.

Дайте мне знать, если вам нужно зашифровать/расшифровать то же самое в NodeJS.

Посетите наш Инсайдерский инженерный блог, чтобы узнать о других решениях, необходимых в реальной жизни:

Ссылки:

[1] Б. Даниэль, Что такое шифрование AES? [Полное руководство по вопросам и ответам], www.trentonsystems.com, 31 марта 2021 г. https://www.trentonsystems.com/blog/aes-encryption-your-faqs- ответил

[2] пакет aes — crypto/aes — пакеты Go, pkg.go.dev. https://pkg.go.dev/crypto/aes#NewCipher (по состоянию на 30 декабря 2022 г.).‌

[3] PHP: openssl_encrypt — Manual, www.php.net. https://www.php.net/manual/en/function.openssl-encrypt.php

[4] PHP: openssl_decrypt — Manual, www.php.net. https://www.php.net/manual/en/function.openssl-decrypt.php (по состоянию на 30 декабря 2022 г.).