Безопасность и Криптография

Прошлогодня лекция о безопасности и конфиденциальности была сфокусирована на том, как вы можете обезопасить свой компьютер с точки зрения пользователя. В этом году, мы сфокусируемся на концепциях безопасности и криптографии, которые that are связаны с пониманием инструментов, обсужденных ранее, такие как использование хэш-функции в Git или such as the use of hash functions in Git или функции получения ключей и симметричные/асимметричные криптосистемы в SSH.

Данная лекция не является заменой более полному курсу по безопасности компьютерных систем (6.858) или криптографии (6.857 и 6.875). Не выполняйте задачи в сфере безопасности без формального обучения безопасности. Если вы не эксперт не запускайте свою крипту. Тот же принцип применим и к системной безопасности.

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

Энтропия

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

XKCD 936: Password Strength

В вышеприведенном XKCD комиксе показано, что пароль типа “correcthorsebatterystaple” более безопасен, чем “Tr0ub4dor&3”. Но как можно посчитать что-то вроде такого?

Энтропия измеряется в битах, и когда вы случайно равновероятно выбираем из множества возможных исходов, энтропия равняется log_2(# of possibilities). Бросок честной монетки дает 1 бит энтропии. Бросок кубика с 6 гранями имеет ~2.58 бита энтропии.

Вам следует считать, что злоумышленник знает модель пароля, но не его случайность (например использование броска кубика для выбора пароля.)

Сколько битов энтропии достаточно? Зависит от модели угроз. Для онлайн угадывания, как в XKCD комиксе, ~40 битов энтропии более чем достаточно. Чтобы быть устойчивым к оффлайн подбору, более сильный пароль необходим (например 80 или больше бит).

Хэш-функции

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

hash(value: array<byte>) -> vector<byte, N>  (for some fixed N)

Примером хэш-функции является SHA1, которая используется в Git. Она соотносит вход произвольного размера к 160-битному выходу (который может быть представлен как 40 шестнадцатеричных символов). Мы можем попробовать SHA1 хэш-функцию на входе, используя команду sha1sum:

$ printf 'hello' | sha1sum
aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d
$ printf 'hello' | sha1sum
aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d
$ printf 'Hello' | sha1sum 
f7ff9e8b7bb2e09b70935a5d785e0cc5d9d0abf0

Верхнеуровнево, про хэш-функцию можно думать как про функцию, к которой тяжело подобрать обратную, а также функцию, которая выглядит случайной (но является детерменистической) (и это идеальная модель хэш-функции). Хэш-функция имеет следующие свойства:

Заметим: SHA-1 больше не является сильной криптографической хэш-функцией. Вы можете найти таблицу жизни криптографических хэш-функций. Однако рекомендация определенных хэш-функций выходит за пределы данной лекции. Если вы выполняете работу, где выбор хэш-функции имеет значение, вам следует пройти формальное обучение по безопасности/криптографии.

Приложения

Функция формирования ключа

Понятие, связанное с криптографическими хэшами, Функция формирования ключа (KDF) используются для большого числа приложений, включая генерацию выхода фиксированной длины для использования в качестве ключа в других криптографических алгоритмах. Обычно, KDF специально медленны, для того, чтобы замедлить оффлайн атаки подбором (brute-force attacks).

Приложения

Симметричная криптография

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

keygen() -> key  (this function is randomized)

encrypt(plaintext: array<byte>, key) -> array<byte>  (the ciphertext)
decrypt(ciphertext: array<byte>, key) -> array<byte>  (the plaintext)

Функция encrypt имеет свойство, что при данном выходе (ciphertext) сложно понять без ключа, какой был вход (plaintext). Функция decrypt имеет очевидное свойство корректности: decrypt(encrypt(m, k), k) = m.

Пример симметричной криптосистемы, имеющий широкое использование сегодня - AES.

Приложения

Асимметричная криптография

Термин “асимметричнай” относится к наличию 2х ключей с двумя разными ролями. Приватный ключ, как подразумевает имя, предназначен для того, чтобы его держали в приватном месте, в то время как публичный ключ может быть публично распространен и это не повлияет на безопасность (в отличии от распространения ключа в симметричной криптосистеме). Асимметричная криптосистема предоставляет следующий набор функций для шифровки(encrypt)/дешифровки(decrypt) и для подписи(sign)/удостоверения(verify):

keygen() -> (public key, private key)  (this function is randomized)

encrypt(plaintext: array<byte>, public key) -> array<byte>  (the ciphertext)
decrypt(ciphertext: array<byte>, private key) -> array<byte>  (the plaintext)

sign(message: array<byte>, private key) -> array<byte>  (the signature)
verify(message: array<byte>, signature: array<byte>, public key) -> bool  (whether or not the signature is valid)

Функции encrypt/decrypt имеют свойства похожие на их аналоги в симметричных системах. Сообщение может быть зашифровано с использованием публичного ключа. При конкретном выходе (ciphertext), сложно определить вход (plaintext) без приватного ключа. Функция decrypt имеет свойство корректности: decrypt(encrypt(m, public key), private key) = m.

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

Функции sign/verify имеют те же свойства, что и физические подписи, в том смысле, что трудно подделать подпись. В независимости от сообщения, без приватного ключа, сложно сделать такую подпись, что verify(message, signature, public key) вернет true. И конечно, функция verify имеет свойство корректности verify(message, sign(message, private key), public key) = true.

Приложения

Распределение ключей

Асимметричная криптография - это замечательно, но она имеет большую проблему распространения публичных ключей / соотнесения публичного ключа к реальному человеку Есть много решений этой проблемы. Signal имеет простое решение: доверять при первом использовании, и поддерживать out-of-band обмен публичными ключами (вы подтверждаете “безопасные номера” ваших друзей при личной встрече). PGP имеет другое рещенеи, которое называется web of trust. Keybase имеет еще одно решение, которое называется social proof. Каждая модель имеет свои преимущества; Мы (инструкторы) предпочитаем модель Keybase.

Изучение на примерах

Менеджер паролей

Это инструмент, который каждый должен попробовать использовать (напрмер KeePassXC, pass, и 1Password). Менеджеры паролей делают удобным использование уникальных, случайно сгенерированных паролей с высокой энтропией для каждого из ваших логинов, и они сохраняют все ваши пароли в одном месте, которое зашифрованно с помощью симметричного шифра с ключем, который сгенерирован из passphrase с использованием KDF.

Использование менеджера паролей позволяет вам избежать переиспользования паролей (вы меньше подвержены, если какой-то из веб-сайтов оказался скомпрометированным), использовать высоко энтропийные пароли ( вас сложнее взломать ), а также вам будет неообходимо запоминать только 1 пароль (passphrase).

Двухфакторная аутентификация

Двухфакторная аутентификация (2FA) требует, чтобы вы использовали passphrase (“что-то что вы знаете”) вместе с 2FA аутентификатором (например YubiKey, “что-то что у вас есть”) для того, чтобы защить вас от кражи паролей и фишинговых атак.

Шифрование диска

Полное шифрование диска вашего компьютера - простой способ обезопасить ваши данные в случае, если ваш компьютер будет украден. Вы можете использовать cryptsetup + LUKS на Linux, BitLocker на Windows, или FileVault на macOS. Они зашифруют весь диск с помощью симметричного шифра, с ключем защищенным с помощью passphrase.

Приватные переписки

Используйте Signal или Keybase. Сквозная защита обеспечивается с помощью асимметричного шифрования. Получение публичных ключей ваших контактов самый важный шаг. Если вы хотите высокой степени безопасности, вам надо верифицировать публичные ключи out-of-band (с Signal или Keybase), или довериться социальным доказательствам (Keybase).

SSH

Мы обсудили использование SSH в предыдущих лекциях. Давайте посмотрим на его криптографические аспекты.

Когда вы запускаете ssh-keygen, он генерирует асимметричную пару ключей public_key, private_key. Она генерируется случайно, используя энтропию, предоставленную операционной системой (которая складывается из событий в железе и т.д.). Публичный ключ сохраняется as-is (он публичный, поэтому не надо его шифровать), однако приватный ключ должен быть зашифрован на диске. ssh-keygen программа предлагает пользователю использовать passphrase, и она используется для KDF функции для генерации ключа, который затем использует для шифровки приватного ключа симметричным шифром.

При использовании, как только сервер узнает публичный ключ клиента ( сохраняется в файл .ssh/authorized_keys), подключающийся клиент может доказать a connecting client can prove its идентичность использую асимметричную подпись. Это исполняется с помощью challenge-response. Верхнеуровнево, сервер выбирает случайное число и посылает его клиенту. Клиент подписывает это сообщение и отсылает подпись обратно на сервер, который проверяет подпись с записанным публичным ключем. Это доказывает, что клиент обладает приватным ключем, который соответствует публичному ключу, записанному на сервере в файле .ssh/authorized_keys поэтому сервер позволяет клиенту залогиниться

Источники

Упражнения

  1. Энтропия.
    1. Предположим пароль был выбран как конкатенация 4 слов из словаря в нижнем регистре, каждое слово выбрано равновероятно из словаря размера 100,000. Пример такого пароля будет correcthorsebatterystaple. Сколько бит энтропии имеет такой пароль?
    2. Рассмотрим другую схему, где пароль выбирается как последовательность из 8 случайных символов алфавита или цифр (включая нижний и верхний регистры). Пример: rg8Ql34g. Сколько бит энтропии будет в этом случае?
    3. Какой пароль сильнее?
    4. Предположим, злоумышленник может проверять 10,000 паролей в секунды. В среднем, как много времени уйдет на взлом данных паролей?
  2. Криптографические хэш-функции. Скачайте Debian image с зеркала (например с этого Аргентинского зеркала). Перепроверьте хэш (например используя sha256sum) с хэшем, полученным с оффициального сайта Debian (например этот файл расположенный на debian.org, если вы скачале файл по ссылке из Аргентинского зеркала).
  3. Симметричная криптография. Зашифруйте файл с помощью AES, используя OpenSSL: openssl aes-256-cbc -salt -in {input filename} -out {output filename}. Посмотрите содержимое, используя cat или hexdump. Расшифруйте его с помощью openssl aes-256-cbc -d -in {input filename} -out {output filename} и проверьте, что содержимое совпадает с оригиналом, используя cmp.
  4. Асимметричная криптография.
    1. Настройте SSH ключи на компьютере, до которого у вас есть доступ. Вместо использования RSA ключей, как в прикрепленном туториале, используйте более безопасные ED25519 ключи. Убедитесь, что ваш приватный ключ зашифрован с passphrase.
    2. настройте GPG
    3. Отправьте Anish зашифрованное письмо (public key).
    4. Подпишите Git коммит с git commit -S или создайте подписанный Git тэг git tag -s. Проверьте подпись коммита git show --show-signature или тэга git tag -v.

Редактировать страницу.

Лицензия CC BY-NC-SA.