Детерминированное шифрование RSA в Java

Это мой первый вопрос на этом сайте, и у меня есть только базовые математические представления об RSA, так что, пожалуйста, терпите меня! :)

Я пишу веб-приложение на Java для своего последнего учебного года в университете. Это веб-реализация «Pret-a-voter», безопасной системы голосования, для тех, кто слышал о ней.

По сути, моя проблема в том, что я хочу дать кому-то, выполняющему роль аудитора:

  • массив байтов source (открытый текст, который нужно зашифровать)
  • файл открытого ключа RSA
  • байтовый массив «destination», который является результатом моего собственного вычисления шифрованных данных с учетом открытого текста и открытого ключа

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

(Примечание. В этом проекте я работаю с очень маленькими блоками данных - симметричное шифрование не используется вообще ... Я знаю, что это «интересное» использование RSA!)

В любом случае я обнаружил, что в Java, используя

cipher = Cipher.getInstance("RSA");

использует схему случайного заполнения по умолчанию по цене 11 байтов (поэтому с парой ключей 2048 бит можно зашифровать 2048 / 8-11 = 245 байтов). Повторное шифрование одного и того же открытого текста генерирует разные зашифрованные тексты, что, очевидно, не является тем режимом ECB, который мне нужен.

У меня вопрос: следует ли мне использовать следующее?

cipher = Cipher.getInstance("RSA/ECB/NoPadding");

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

Вторая часть моего вопроса больше связана с Java. Если я действительно использую RSA / ECB / NoPadding, как указано выше, я считаю, что могу предоставить исходный массив байтов (скажем) длиной 128 (для пары ключей RSA 1024 бит) и зашифровать его. чтобы получить еще один массив байтов длиной 128. Если я попытаюсь снова зашифровать этот с другим открытым ключом длиной 1024, я получу

javax.crypto.BadPaddingException: сообщение больше модуля

Кто-нибудь знает почему?

РЕДАКТИРОВАТЬ - шифрование с помощью NoPadding не всегда генерирует это исключение - оно темпераментное. Однако даже если шифрование не генерирует это исключение, дешифрование генерирует следующее:

javax.crypto.BadPaddingException: данные должны начинаться с нуля

Большое спасибо, что прочитали это! Любая помощь будет принята с благодарностью.

ИЗМЕНИТЬ - извините, мой первоначальный вопрос был не очень ясен относительно того, что я хочу сделать, поэтому вот [попытка] объяснения:

  • Открытый текст - это голос избирателя на выборах.
  • Pret-a-voter стремится к сквозной проверке без ущерба для конфиденциальности избирателя (и т. Д.). После голосования избирателю выдается квитанция, по которой он может проверить, правильно ли записан его голос, и которая позже покажет ему, что его голос не был подделан. Избиратель сравнивает полученную информацию с идентичной копией, размещенной в сети.
  • Однако ни один избиратель не должен иметь возможности доказать, как он проголосовал (поскольку это может привести к принуждению), поэтому информация представляет собой не открытый текст, а зашифрованную копию голосования.
  • Фактически, открытый текст шифруется четыре раза с четырьмя разными асимметричными ключами, которые хранятся у двух разных кассиров, у каждого из которых есть два ключа. Таким образом, голосование (открытый текст) предоставляется одному кассиру, который шифрует его с помощью открытого ключа # 1, а затем шифрует ЭТО зашифрованный текст своим вторым открытым ключом, передает ЭТО зашифрованный текст второму кассиру, который шифрует его двумя своими ключами одним и тем же способ. Полученный зашифрованный текст (результат четырех последовательных шифрований) - это то, что публикуется в сети (становится общедоступным). Счетчикам доверяют.
  • Каждый зашифрованный голос можно представить себе в виде «луковицы», где в центре находится голос и имеется несколько уровней шифрования. Чтобы попасть на голосование, каждый уровень должен быть удален по очереди, то есть соответствующие закрытые ключи (хранимые кассирами) должны применяться в обратной последовательности. Это ключ к безопасности - все счетчики должны работать сообща, чтобы расшифровать голоса.
  • Электронную доску объявлений можно представить в виде таблицы с 5 столбцами - первый (слева) содержит полностью зашифрованные голоса (также показанные в квитанции каждого избирателя) и является единственным видимым столбцом на этапе голосования. Второй столбец содержит тот же набор голосов, но с удаленным внешним слоем - кассир 2 заполняет этот столбец и столбец 3, расшифровывая голоса, используя свои закрытые ключи на этапе подсчета голосов. В конце этапа подсчета столбец 5 содержит полностью расшифрованные голоса, которые затем могут быть подсчитаны.
  • Каждый избиратель получает квитанцию, которая связывает его с зашифрованным голосом в столбце 1. Это не показывает, как они проголосовали, но позволяет им убедиться, что их голос не был подделан, поскольку на протяжении всего процесса выборов они могут проверять, что их зашифрованный голос все еще находится в столбце 1, нетронутым. Это, конечно, только половина «сквозной проверки», поскольку избиратели не могут проверить, что дешифрование было выполнено правильно, т.е. что в столбце 2 есть запись, которая представляет собой их голос за вычетом внешнего уровня шифрования. . Каждый избиратель несет ответственность только за проверку ДО пункта в графе 1.
  • После этого аудиторы обязаны проверить, что записи в столбце 1 расшифровываются до столбца 2 и так далее. Они делают это, полагаясь на детерминированное шифрование, а открытые ключи, используемые для шифрования, являются общедоступными.
  • Поскольку открытые ключи являются общедоступными, вы не хотите, чтобы люди просто рисовали линии из столбца 5 в столбец 1, присоединяя чей-то голос, поскольку он многократно зашифровывается - таким образом квитанция, которая привязывает вас к зашифрованному голосованию, фактически связывает вас с незашифрованное, читаемое голосование -> принуждение! Таким образом, только столбцы 1, 3 и 5 являются общедоступными (поэтому каждый кассир выполняет ДВА шифрования), и для каждой записи в столбце 3 аудиторам раскрывается только ОДНА из соответствующих записей в {2,4}. Это не позволяет никому (даже аудиторам) связать зашифрованный голос с незашифрованным.
  • Поэтому аудиторам необходимо взять запись в столбце 3, получить соответствующую запись в столбце 2 и открытый ключ и выполнить такое же шифрование, чтобы убедиться, что они действительно получили запись в столбце 2.
  • В совокупности это обеспечивает сквозную проверяемость.

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


person Chris B    schedule 30.03.2011    source источник
comment
Я не думаю, что RSA / ECB вообще имеет смысл, поскольку ECB - это режим цепочки для блочного шифра (или, точнее, отсутствие цепочки). У вас есть ссылка на спецификацию вашего протокола, возможно, вы что-то пропустили.   -  person Bruno Rohée    schedule 30.03.2011
comment
Я узнал о параметре RSA / ECB / NoPadding getInstance здесь: stackoverflow.com/questions/2714327/ К сожалению, спецификации протокола находятся в моей голове и в написанном мной коде - я мог бы опубликовать код, но это огромный проект eclipse и я, наверное, долго читал и объяснял. Есть ли какой-либо другой способ детерминированного шифрования в Java, кроме упомянутого мной параметра NoPadding (который может быть небезопасным, я не уверен, но он, похоже, работает - хотя иногда генерируется сообщение больше, чем ошибки модуля)?   -  person Chris B    schedule 30.03.2011
comment
Есть ли способ, которым я могу заполнить случайное заполнение - так, чтобы зашифрованный текст был постоянным для данного открытого текста и заданного начального заполнения? Затем я мог бы передать это семя одитору.   -  person Chris B    schedule 30.03.2011
comment
Сообщение больше модуля не соответствует действительности, когда это происходит? Вы не должны шифровать длинные вещи с помощью RSA, наиболее практичный протокол шифрует только случайный ключ для симметричного шифра, поэтому некоторые реализации не поддерживают RSA для длинных сообщений, поскольку это имеет небольшую практическую ценность ... В вашем случае вы можете вам нужно заново реализовать RSA, BigInteger был довольно-таки исправным, когда я проверял в последний раз.   -  person Bruno Rohée    schedule 30.03.2011
comment
Кстати, из того немногого, что я получил от протокола, я не считаю его безопасным, возможно, вам следует при каждом голосовании зашифровать с помощью ключей верификатора достаточно информации, чтобы они его подтвердили, но предсказуемое шифрование вообще не звучит правильно, вы изо всех сил, чтобы удалить функции безопасности ...   -  person Bruno Rohée    schedule 30.03.2011


Ответы (3)


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

Случайное заполнение останавливает это, потому что злоумышленник не знает, какое заполнение добавить.

Вам нужно будет использовать обычное заполнение, но раскрыть подмножество закрытых ключей подмножеству аудиторов (обычно называемых «наблюдателями» в избирательных системах). Это означает, что один контролер может подтвердить, что столбец 1 соответствует столбцу 2, другой может подтвердить, что столбец 2 соответствует столбцу 3, и так далее. Индивидуальный наблюдатель не может сопоставить избирателя с бюллетенем, только сотрудничающих с ним.


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

person caf    schedule 31.03.2011
comment
Большое спасибо за ваши мысли. Один ключевой момент, который я забыл упомянуть, заключается в том, что зашифровывается циклический сдвиг списка кандидатов (который вращается на любое целое число по модулю N (для N кандидатов) в каждом бюллетене) - позиция X хранится в обычном виде. Однако есть также семена, которые добавляются на каждом этапе шифрования, чтобы злоумышленник не мог зашифровать с помощью четырех ключей, как вы говорите - они не знают, какие семена использовать, и, следовательно, не знают, как должен выполняться циклический сдвиг. быть обращенным (по значению семени) на каждом этапе. - person Chris B; 31.03.2011
comment
... учитывая это, могу ли я вернуться к отсутствию заполнения? Или мне все же лучше посмотреть на раскрытие подмножества закрытых ключей подмножеству проверяющих? Кроме того, как бы невероятно это ни звучало, способ, которым я делал это до сих пор для повторного шифрования 128-байтовых массивов (в java, с использованием случайного заполнения по цене 11 байтов), заключается в добавлении 4-байтового целого числа к байту [] и переместите первые 15 байтов в поле базы данных переполнения. При расшифровке эти переполнения добавляются соответствующим образом. Совсем не идеально, но это сработало - я столкнулся с проблемами только тогда, когда обнаружил, что он не детерминированный. - person Chris B; 31.03.2011
comment
@Chris: Поскольку количество кандидатов N обычно очень мало, неизвестный циклический сдвиг не сильно увеличит работу злоумышленника - им просто нужно попробовать все N возможных сдвигов открытых текстов. - person caf; 01.04.2011
comment
Моя идея заключалась в том, чтобы иметь (потенциально) большой циклический сдвиг с диапазоном, скажем, 2 ^ 32, и использовать этот по модулю N как фактический сдвиг, так что, надеюсь, это будет нормально. Однако, обдумывая различные способы, которыми я мог бы сохранить этот проект, и часы, которые я уже потратил, не перепроектируя с нуля, я думаю, что ваше решение - придерживаться случайного заполнения и давать частный ключ или два каждому аудитору. , это тот, который я буду использовать. Я все еще хотел бы, чтобы можно было просто дать им открытый текст + PK и попросить их проверить мой расчет зашифрованного текста, но не беспокоиться. Спасибо за помощь :) - person Chris B; 01.04.2011
comment
@Chris: Проблема в том, что значение имеет только значение после mod N - все другие возможные значения эквивалентны одному из значений циклического сдвига 0 ... N-1. Без проблем. Если на вашем факультете есть кто-то с глубоким пониманием математики RSA, который может просмотреть вашу схему, это, вероятно, будет хорошей идеей. - person caf; 02.04.2011

https://en.wikipedia.org/wiki/RSA_ (криптосистема) #Padding < / а>

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

person Paul Ruane    schedule 30.03.2011
comment
Спасибо за это. У вас есть опыт этого на Java? Если я выберу RSA / ECB / NoPadding, придется ли мне использовать входные данные размером 2 ^ N байтов? Я просто заполняю его нулями? Извините, если это предложение смешно - я так много читал, но все еще не понимаю, как достичь того, что мне нужно. Я добавил несколько пунктов в конце своего вопроса, объясняя, что мне нужно делать, если это поможет. Еще раз спасибо! - person Chris B; 31.03.2011
comment
Нет, у меня нет личного опыта в этом. Вы можете ответить на вопрос о нулевом заполнении с помощью простого эмпирического теста. Судя по вашим пунктам, я не могу не думать, что в некоторых случаях криптографический хеш может быть не лучше. Но завтра я перечитаю. - person Paul Ruane; 31.03.2011

Мне кажется, что у вас есть 2 основных требования, которые вы пытаетесь использовать deterministic RSA для решения:

  1. Разрешение избирателям гарантировать честность своего голосования
  2. Разрешение аудиторам гарантировать честность всех голосований

Цифровые подписи должны решить эту проблему. Вы можете взять зашифрованный текст из столбца 1, хешировать его и зашифровать хеш с помощью закрытого ключа. Затем этот зашифрованный хэш можно поместить в столбец 2. Чтобы проверить целостность столбца 1, просто используйте соответствующий открытый ключ для расшифровки хеша в столбце 2, столбце хеширования 1 и сравните эти 2 значения. Если они равны, данные не были подделаны. Только стороны, у которых есть закрытый ключ, могут вмешиваться в данные в этих столбцах, потому что только они могут создать соответствующую пару. Это похоже на HMAC, но имеет преимущество использования открытых / закрытых ключей, а не секретного общего ключа. Таким образом, любой может проверить, но только доверенные стороны могут изменить.

Что касается детерминированной схемы, то следует отметить, что она может приводить к утечке информации разными способами. Предположим, я знаю, что проголосовал за Blue как за свой любимый цвет. Я вижу, что полученный зашифрованный текст моего голоса - 0x12345678. Если схема полностью детерминирована, я знаю, что любой, у кого есть соответствующий зашифрованный текст 0x12345678, также голосовал за Blue. Кроме того, поскольку обычно у вас есть ограниченный набор вариантов голосования, выбранная атака открытым текстом является невероятно просто. Таким образом, вы действительно хотите, чтобы RSA выполняла свою работу и использовала предполагаемую схему заполнения.

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

person Luke    schedule 30.03.2011
comment
Большое спасибо (всем) за чтение и за ваши комментарии. Я не уверен, что мне нужен HMAC - я добавил несколько пунктов внизу вопроса, чтобы попытаться прояснить, почему я хочу, чтобы шифрование RSA было детерминированным. Но я могу чего-то упустить или не вижу альтернативы - если у вас есть время взглянуть и / или сообщить мне, может ли HMAC все еще работать, я был бы очень признателен. Спасибо. - person Chris B; 31.03.2011
comment
Я сделал еще один выстрел. Вы правы, HMAC не совсем соответствовал вашим потребностям, но я думаю, что цифровые подписи подходят. Я думаю, что то, что вы пытались сделать, в любом случае было близко к цифровой подписи. Прежде всего, я настоятельно призываю вас не использовать RSA так, как вы пытаетесь его использовать. Это будет небезопасно. - person Luke; 31.03.2011
comment
Прочитав все ответы / комментарии, я думаю, что ваше (шифрование хэша с помощью закрытого ключа и распространение открытого ключа аудиторам, которые могут использовать его для расшифровки и проверки целостности хэшей) может быть лучшим решением ... Я не слышал о шифровании с закрытым ключом / расшифровке открытого ключа раньше, не знал, что это возможно с RSA - нужно будет прочитать об этом. Большое спасибо за идею. Выбранная атака с открытым текстом не сработает, поскольку зашифрованная информация на самом деле представляет собой циклический сдвиг списка кандидатов, который представляет собой большое количество (подлежащее шифрованию) по модулю N кандидатов. - person Chris B; 31.03.2011
comment
Надеюсь, это сработает для вас, я с радостью отвечу на любые другие вопросы, которые могут у вас возникнуть. Я думаю, что, используя криптографические строительные блоки так, как они были задуманы, вы обнаружите, что у вас есть все необходимое для выполнения вашей задачи. Хитрость заключается в том, чтобы выяснить, какие блоки использовать в каких местах. - person Luke; 31.03.2011
comment
Потратил некоторое время на размышления об этом, и хотя я уверен, что это более или менее решение, мне все еще не совсем понятно, как это будет работать. Цель состоит в том, чтобы убедить избирателей в том, что 4x зашифрованные голоса в столбце 1 на самом деле являются голосами в столбце 5, только что зашифрованными и перемешанными. Cols 1,3,5 общедоступны. Для каждой записи в столбце 3 аудитору показывается ссылка на 1 или 5 (через 2 или 4 соответственно; их выбор, так что каждый может быть достаточно уверен, что все ссылки верны). Делая то, что вы говорите - столбец хеширования 1, затем четырехкратное шифрование закрытого ключа в столбцах 2-5, никто не может взять ... - person Chris B; 31.03.2011
comment
... 4x зашифрованный хэш в столбце 5, затем расшифровать с помощью 4 открытых ключей, чтобы связать голосование в столбце 5 с зашифрованным голосом в столбце 1 - путем последовательного выполнения дешифрования открытого ключа для каждого ключа? - person Chris B; 31.03.2011
comment
Похоже, вы действительно хотите подписать пятую колонку, не так ли? Если столбец 5 - это их голосование открытым текстом, вы хотите, чтобы они были уверены, что их фактический голос был записан должным образом (способом, который также может быть проверен аудиторами). Зашешируйте открытый текст голосования, зашифруйте его закрытым ключом и предоставьте открытый ключ для проверки. Поместите это в свой стол. Когда я хочу проверить, я беру свой голос (я знаю, какой был мой голос), хеширую его и сравниваю хеш с хешем из таблицы после того, как расшифровываю его с помощью открытого ключа. - person Luke; 31.03.2011
comment
Ах, причина, по которой только аудиторы могут проводить аудит за пределами столбца 1, заключается в том, что избиратели не должны иметь возможность показать, как они проголосовали (принуждение и т. Д.), Поэтому на самом деле избиратель может только сравнить свою квитанцию ​​с чем-то в столбце 1, при этом работают только два счетчика возможность совместно сгенерировать 2, 3, 4 и, в конечном итоге, 5. Аудиторы должны проверять 1-2-3 (т. е. 1 - это 2 зашифрованных, а это 3 зашифрованных) XOR 3-4-5 для каждого значения в 3, обеспечивая разумные уверенность в том, что 1 расшифровывает до 5. Вот почему было бы так легко, если бы я мог просто дать ключи паба и сказать аудиторам зашифровать 3 к 2 и 2 к 1 :) Большое спасибо. - person Chris B; 31.03.2011
comment
Извините, мне очень сложно разобраться в требованиях, столбцах и том, что они делают. Наилучший способ решения этой проблемы - это, скорее всего, начать с простого с самого начала с ваших основных требований, а затем спроектировать систему с помощью простых строительных блоков для достижения каждого требования. Я думаю, проблема в том, что вы зашли слишком далеко по одному пути, потому что сделали предположения, которые оказались неверными (например, детерминированное использование RSA). Или, может быть, вы слишком заняты на этом этапе, и лучше просто форсировать то, что у вас есть. - person Luke; 31.03.2011
comment
Вы определенно правы в том, что сделали неверные предположения и в результате зашли слишком далеко по неверному пути ... Я подозреваю, что мне нужно форсировать то, что у меня есть, как вы говорите, но у меня очень много оружия теперь больше знаний, чем было раньше, так что большое спасибо за это :) - person Chris B; 31.03.2011