Ключевые данные и IV для AES в Tcl

У меня есть инструмент на основе tcl/tk, который использует сетевой пароль для аутентификации. Проблема в том, что он сохраняет пароль в журналах / истории. Поэтому цель - зашифровать пароль.

Я пытался использовать пакет aes. Но в самом начале aes::init запрашивает ключевые данные и вектор инициализации (16 байт). Итак, как генерировать IV и ключевые данные. Это какое-то случайное число? Я новичок в алгоритмах шифрования.

2 ответа

Если у вас есть пароль в журналах / истории, почему бы не исправить ошибку регистрации / хранения в первую очередь?

В противном случае есть отдельные вещи, которые вы могли бы хотеть:

  1. Схема хеширования пароля, такая как PBKDF2, bcrypt, argon2 и т. д. для безопасного хранения пароля и сравнения с ним вводимых пользователем данных. Это обычно тот случай, когда вам нужно реализовать какую-то аутентификацию с паролями на стороне сервера.

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

  3. У вас есть некоторые секретные данные, и вам необходимо хранить их в незашифрованном виде.

Если у вас есть случай 1, не используйте aesпакет, это неправильный инструмент для работы. Если у вас есть случай 2, то aes Пакет может помочь вам, но вы только что обменялись проблемой сохранения пароля в секрете с другой проблемой сохранения ключа в секрете (не большой выигрыш). Так что единственный жизнеспособный случай, когда aes это вариант может быть 3.

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

AES имеет несколько возможных режимов работы, наиболее распространенными из которых являются: ECB, CBC, OFB, GCM, CTR, Пакет Tcllib просто поддерживает ECB а также CBC, и только CBC (который используется по умолчанию) - это действительно вариант для использования. Посетите Википедию для примера, почему вы никогда не должны использовать ECB Режим.

Теперь вернемся к вашему актуальному вопросу:

Вектор инициализации (IV)

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

Секретный ключ

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

Где взять хорошую случайность?

Если вы используете Linux, BSD или другие Unixoid системы, просто читайте байты из /dev/urandom или используйте обертку для getrandom(), НЕ используйте Tcls expr {rand()} или аналогичные генераторы псевдослучайных чисел (PRNG). На Windows TWAPI и тому CryptGenRandom Лучше всего было бы использовать функцию, но, к сожалению, в нее не входит высокоуровневая оболочка Tcl.

Этого достаточно?

Зависит. Если вы просто хотите скрыть немного открытого текста от поверхностного взгляда, может быть. Если у вас есть злоумышленники, манипулирующие вашими данными или активно пытающиеся взломать вашу систему, тем более. На простом AES-CBC есть много вещей, которые вы можете сделать неправильно, и даже эксперты ошиблись (читайте о проблемах SSL/TLS 1.0 с AES-CBC).

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

Если я читаю вики-страницу Tcler на aes, я вижу, что зашифрую, выполнив это:

package require aes

set plaintext "Some super-secret bytes!"
set key "abcd1234dcba4321";                        # 16 bytes

set encrypted [aes::aes -dir encrypt -key $key $plaintext]

и я расшифровываю, делая:

# Assuming the code above was run...
set decrypted [aes::aes -dir decrypt -key $key $encrypted]

Обратите внимание, что расшифрованный текст имеет NUL (ноль) байтов, добавленных в конце (8 из них в этом примере), потому что алгоритм шифрования всегда работает с блоками по 16 байтов, и если вы работаете с текстом не-ASCII, то encoding convertto а также encoding convertfrom может быть необходимо.


Вам не нужно использовать aes::init непосредственно, если вы не делаете масштабное потоковое шифрование. Ваш вариант использования не звучит так, как будто он нуждается в подобных вещах. (Ключевыми данными является ваш "секрет", а вектор инициализации является чем-то стандартизированным, что обычно вам не нужно устанавливать.)

Другие вопросы по тегам