Шифрование отдельных файлов с помощью cryptsetup/LUKS
> можно вспомнить про ... cryptsetup/LUKS, которыми тоже в принципе можно шифровать файлы, причём с помощью LUKS в plain mode ... с нужными параметрами и правильно сгенерённым паролем вроде как это будет надёжно бессигнатурно.
Разобрался, как шифровать отдельные файлы с помощью openssl:
(Если есть ошибки, прошу указать.)
Просьба подсказать, как подобное осущеcтвить с помощью cryptsetup или LUKS. Интересует не столько бессигнатурность, сколько простота действий. Конкретно, хотелось бы шифровать по паролю без использования асимметрики. Многократное чтение man cryptsetup и гугление, в том числе на pgpru.com, не помогли.
Появляется шированное устройство /dev/mapper/name, на которое можно записывать например поблочно командой dd. Наверное проще создать на нём файловую систему, примонтировать её и записать файл стандартным способом
По завершении работы все действия произвести в обратном порядке
Команды не проверял, но скорей всего должно работать, т.к. ранее воспроизводил это неоднократно.
комментариев: 9796 документов: 488 редакций: 5664
комментариев: 9796 документов: 488 редакций: 5664
Процедура изъятия VPS — это нечто интересное само по себе.
Спасибо за корректную простановку ссылки, это облегчило поиск. Как вы, наверное, знаете, там в комменте идёт отсылка к этому примеру. Обратите внимание, что для бессигнатурности там используются трюки. Кроме того, там есть кое-какие предостережения в плане IV (неохота вспоминать) и KDF для шифрования (KDF вроде как нет вообще). Если честно, шифровать файлы openssl'ем — это коряво ввиду озвученных косяков. Если бы лично мне позарез понадобилось бессигнатурно зашифровать файл, я бы воспользовался plain mode cryptsetup (как ФС на файле или непосредственно), а если просто зашифровать, то GnuPG.
Это не является штатной опцией cryptsetup, но из имеющихся опций неявно следует, что так можно сделать. Гугление могло бы помочь, только если какой-то гуру выложил бы рецепт. В общем, это пример как раз достойного вопроса для уровня pgpru.
Можно сделать и пофайлово, но это только для извращенцев и через скриптомесево.
Не нужно. Файл может передаваться как аргумент напрямую cryptsetup'у, он сам из него сделает блочное устройство.
+1. Это будет работать быстро, штатно и везде, в отличие от пофайлового шифрования. К тому же, так можно легко добавлять туда и несколько файлов (хотя если процедура заточена под один конкретный, то всегда можно предварительно создать архив).
Это не трюкачество, а дебилизм с фатальным непониманием матчасти. Блочные устройства, в отличие от файлов, не даунскейлятся с секторов на байты. Если из файла сделать LUKS-устройство, то его отмапленная часть будет обрезана до целого числа секторов. Как туда запихать файл? Либо в конце будет свободное место, либо файл обрежется, и как его потом оттуда извлекать? Получается костыльно, но придётся писать и файл и его размер и ещё учесть округление до секторов. Показываю мастер-класс. Оно работает, причём правильно (сравнивал по хэшам шифруемого и расшифрованного файлов). Я проверял.
Скриптомесево №3
Скрипт шифрования luks_encrypt.sh:
Как это работает
Зашифровать файл:
комментариев: 11558 документов: 1036 редакций: 4118
Равно, как и на той же системе после очередного обновления.
У меня в памяти отложился инцидент с mcrypt. Я ради бессигнатурности раньше им шифровал соль (опция -b). Потом я поставил другую ОС, где была другая версия mcrypt, и всё. Старые файлы расшифровываться перестали. Хорошо, у меня был доступ к предыдущей ОС'и, поэтому я смог перешифровать те файлы, но вообще пример показательный.
Хотелось поберечь нервы разметка-куну. Это Вам спасибо, что заметили, и за очередную порцию "информации к размышлению".
Благодарю всех за ответы. И вдруг, и неожиданно вопрос оказался, как всегда, совсем-совсем непростым. :-)
Можно было бы в стиле unknown-SATtva указать на общие факты, которых достаточно для написания готового скрипта, если знать матчасть, но, конечно, готовый инструмент — это готовый инструмент, а не заметки на коленке. Мне вот матчасть пришлось доизучить на ходу, потому что изначально не было очевидно, что любое блочное устройство состоит из
секторовблоков (слегка тавтологично, но, тем не менее), и их нецелое число там не сделать никак. Кстати, размер сектора/блока на разных системах может быть разным, но я отличного от 512 не видел (может быть, где-то ещё 128 или 256 было?).Ещё одна тонкость — извраты с dd. Здесь они не так сильно вылазят, потому что идёт запись в блочное устройство, размер которого не может быть изменён, но вот если бы запись делалась в файл, всё было бы тоньше. Наверно, тем, кто с этим работал, это покажется тривиальным, но вообще логика там не такая очевидная. Например, при dd в файл с seek=X будет автоматически создано X блоков нулей, а потом в конец добавлен контент. Если запись таким образом идёт в середину файла, всё до середины будет оставлено, как есть, после середины добавлен контент, а оставшаяся часть будет (сюрприз!) обрезана. Т.е. как по уму записывать фиксированный набор байтов в фикисрованное место файла, ничего не обрезая, — для меня осталось вопросом (который в некоторых частных случаях решается теми или иными хаками, но, наверно, можно и проще).
Ещё одна тонкость была — как записать и считать размер файла. Можно было бы сделать сложнее и оптимальней: не тратить на это лишний сектор, а вычислять необходимое минимаьное число секторов для записи и файла и его «заголовка», где потом распознавать, где файл, а где заголовок, по определённым меткам. Впрочем, раз 4096 секторов и так уже расходуется чисто под заголовок LUKS, будет там на один сектор больше или меньше — уже не важно (для бессигнатурки, не отягощаемой LUKS-заголовком, это имело бы больше смысла).
При считывании размера файла через dd формально пишется на вывод терминала всё хорошо, но с точки зрения внутренностей шелл не считает это цифрами, потому что там нули. И, кстати, очень хорошо, что там нулевые байты — это не ноль в смысле цифры в десятичной системе, а то было бы совсем весело. :-) В общем, хак со strings как-то решает эту проблему, вырезая нужное, но я не уверен, что именно так делается считывание ASCII-символов из файлов в скриптах. Хотелось бы почитать что-то грамотное на тему, как писать в файлы и читать из них, а не переизобретать велосипеды на коленке.
Хотелось бы, чтоб кто-нибудь подсказал. Такое впечатление, что dd читает и пишет блоками, причём количество считанного и записанного должно быть кратно размеру блока. Более того, оффсеты в читаемом и записываемом тоже задаются кратными размеру блоков, тут же надо сделать отступ 512, который не кратен размеру файла. Просто записать произвольный размер — это bs=размер count=1 (не знаю, как это будет работать на больших файлах). Я пытался сделать с seek_bytes=1 и skip_bytes=1, но на вторую опцию dd начал почему-то жаловаться. Понятно, что можно из одного dd сделать несколько и решить эти проблемы, но хотелось бы это записывать покороче и без усложнения логики. В текущем скрипте при расшифровании запись всего 200KB/s. Это очень медленно, но для небольших текстовых файлов сойдёт.
Наконец, замечание общего характера: на мой взгляд, не нужно. Во-первых, это требует скрипт, который надо где-то хранить (хотя его смысл прост, можно и руками извлекать, если это бывает нужным очень редко). Во-вторых, единственное применение, где это могло бы быть осмысленным — удалённые бэкапы, но бэкапится обычно не один файл, а много. Раз их много, проще оценить минимальный размер необходимой ФС и сделать всё штатно через ФС на файле. Впрочем, одно из применений всё же имеется, но там нужен именно бессигнатурный вариант — это пересылка файлов через файлообменники и другие недоверенные сервисы, где не хочется светить информацию о том, чем были зашифрованы файлы, и вообще, мусор это или шифрованные данные.
комментариев: 9796 документов: 488 редакций: 5664
Для CD/DVD вроде как 4096.
dd bs=1c — размер блока в один байт.
Есть ещё опасение насчёт криптостойкости. Если делать tar -c -f- /[path]/* | gpg -c > file.tar.gpg, то у нас всё точно корректно зашифруется: будет правильная обработка пароля, уникальный (случайный, каждый раз разный) вектор инициализации для всего файла, даже если шифровать несколько раз одно и тоже одинаковым паролем и давать копии этого противнику и т.д. А при нестандартном использовании cryptsetup можно напортачить и незаметить этого.
Там так и стоит:
Вы имеете в виду, что режим поблочного шифрования не такой же хороший, как в GnuPG? Было предостережение на предмет того, чтобы не давать противнику видеть шифртекст контейнера с разным его содержимым (в разное время) [атака уборщицы]. Тут, правда, контейнер одноразовый, поэтому в лоб такого не будет происходить, но мало ли...
Хуже, если шифрование будет бессигнатурным. Там пароль один и несменяемый.
© man cryptsetup ← лично мне непонятна вот эта магия. Откуда в норме берётся IV в plain mode? А в LUKS? Нужно ли под IV выделять отдельный сектор? И т.д.
комментариев: 9796 документов: 488 редакций: 5664
В GnuPG — достаточно хороший режим и протокол для файлового шифрования, в dmcrypt — достаточно хороший для шифрования ФС. Использовать режимы GnuPG для ФС — грозит однозначным фэйлом в ряде ситуаций. А можно ли использовать режимы dmcrypt для файлов? Можно долго разбирать теорию, но проще решить, что лучше так не делать.
Статическая псевдорэндомизация, синтетический IV: IV = Hash(номер сектора ║ ключ ║ содержимое предыдущего сектора ║ что-то ещё, могут быть варианты). Это примерно так в ESSIV. Любителям придираться: формула от балды, пироги с сапогами и всё-такое. Использовать только для иллюстрации принципа. В XTS всё ещё сложнее.
Если ФС на файле, и эта ФС не меняется без полного пересоздания всего и вся, то чем плохо? Я не вижу причин.
Думаю, можно. Шифрование ФС влечёт за собой более жёсткие требования, чем шифрование файлов, потому что, как вы говорили, ФС целиком не перешифровывается при изменении содержимого некоторых секторов. Но в случае вышеприведённого скрипта всё это и не нужно: генерируется ключ, записывается в LUKS-слоты, этим ключом шифруется содержимое блочного устройства (куда записан файл); содержимое блочного устройства после этого никогда не меняется. Если в этой схеме есть уязвимость, то она, тем более, есть и при шифровании ФС. Я не вижу, чем этот случай отличается от случая «отдал противнику свой диск, шифрованный LUKS'ом».
Я не про то, как это внутренне устроено, а про примитивное юзерское. Если по простому: в каких случах нужно указывать --skip, и какой в этом будет смысл? Могли бы вы привести наглядные примеры? Во всех случаях (бессигнатурка, бессигнатурка с оффсетом (шифруем неразмеченное дисковое пространство начиная с какого-то сектора)] я пока что нигде эту опцию не использовал. Это правильно? Где она может быть нужна?
А, Вы об этом. :-) Этим я пытаюсь проявить элементарную вежливость в общении. Увидел, что другие так делают, и тоже так поступаю. Без таких ссылок читатель/отвечающий будет тратить лишнее время.
Бессигнатурно шифровать openssl можно без трюков
IV создаётся на основе пароля, но можно указать опцией -iv, тогда при расшифровке его необходимо помнить. Удобно также шифровать mcrypt
Плюс в том, что IV генерится из рандома и записывается перед шифртекстом, поэтому помнить не нужно. Тоже убирается опцией noiv, тогда будет создаваться из пароля, как в openssl. Другой плюс это 256-битный блок Rijndael, в отличие от 128-битного в openssl, а также больше выбор алгоритмов, включая Twofish и Serpent.
Если файл примонтирован как устройство, то при записи в середину он не может обрезаться. Кстати, забыл написать в comment91420, что перед связыванием файла с блочным устройством, его нужно чем-нибудь заполнить до нужного размера, если он пустой. Например для 10 мегабайт
IV-соль в plain не используется, т.к. пароль не шифруется, а преобразуется в ключ хешированием или испольуется напрямую (aes-plain). При использовании LUKS IV для шифрования ключа паролем берётся из /dev/urandom по умолчанию (можно изменить опцией --use-random) и сохраняется в заголовке. Для шифрования блоков диска IV со стороны вообще не используется, а генерится из ключа по алгоритму ESSIV (как unknown показал).