2017-02-01 3 views
4

Мы используем Java-библиотеку с именем license3j для управления лицензиями. Библиотека использует асимметричное шифрование и полагается на Bouncycastle. Мы создаем файл лицензии с помощью простой команды gpg и проверяем лицензию в нашем программном обеспечении с помощью нашего открытого ключа. Пока все работало нормально. НО: В 1000 сгенерированных лицензий имеется очень небольшая часть, которая не может быть проверена правильно, хотя они действительно действительны (приблизительно 5/1000).Недопустимая длина подписи при вызове PGPOnePassSignature.verify

Что происходит в этом случае: когда лицензия должна быть проверена в com.verhas.licensor.License.setLicenseEncoded(InputStream), то org.bouncycastle.openpgp.PGPOnePassSignature.verify(PGPSignature) выдает следующее исключение:

org.bouncycastle.openpgp.PGPRuntimeOperationException: unable to verify signature: Signature length not correct: got 511 but was expecting 512

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

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

gpg --armor --local-user=name.of.software --sign 

Это даст нам файл лицензии.

Произошла ошибка во время Проверка? Нужно ли мне модифицировать любую конфигурацию Bouncycastle для правильной адресации нулевой проблемы? Их FAQ дает некоторые подсказки, но , очевидно, никогда не использует какой-либо экземпляр Cipher, поэтому я полностью потерял возможность интегрировать его в данный API.

Я знаю, что это особая проблема с библиотекой, которая, очевидно, не очень хорошо известна. Таким образом, я ценю любую небольшую обратную связь или ввод.

ответ

4

Похоже, это ошибка в BouncyCastle, только встречается в версиях Java после 1.6, BouncyCastle всегда создал данных неправильно, но Java стал более строгим, так как 1.7 в данном он будет принимать во время проверки.

Bouncycastle не вставляет подписи под нужную длину, когда он сериализует его в файл, если целое число имеет достаточно старших нулей, тогда его байт будет меньше.
Версии Java версии 1.7 и выше ожидают, что байты RSA-подписи будут иметь ту же длину, что и ключ.

Bouncycastle преобразует массив байтов RSA-подписи (возвращенный поставщиком Java JA Java) в целое число и отбрасывает информацию о его длине.
Line 263 of the PGPSignatureGenerator показывает, где байты RSA-подписи возвращаются из JCE и преобразуются в целое число.

Это целое число в конечном итоге записывается в выходной поток, используя MPInteger#encode, который просто использует длину бит базового объекта для определения количества данных для записи.

This answer описывает больше о том, почему вы видите это aproximatley в каждом 200 случаях и как играет роль Java.

+0

Спасибо Магнусу, что действительно помогло понять проблему! Есть ли у вас какие-либо предложения, как я мог бы решить эту проблему с помощью управляемых усилий? Прохождение через источник BC не показывает какой-либо момент, в который я мог бы зацепиться. Есть ли альтернативы, которые я мог бы использовать? – qqilihq

+1

К сожалению, фиксация его в bouncycastle выглядит нетривиальной, вы можете попытаться собрать ошибку в своем трекер-проблеме, но я не уверен, сколько у вас будет успеха. Хакерная работа может состоять в том, чтобы попытаться проверить каждую лицензию и восстановить ее, если она не удалась. – Magnus

+0

На самом деле у меня также возникла идея с регенерированием лицензий, но наш сервер, на котором генерируются лицензии, не работает в среде Java. Было бы огромной лавой, чтобы создать JRE только для проверки лицензий. Я попытаюсь поднять вопрос в BC об этом. Еще один вопрос: существуют ли еще крипто-библиотеки рядом с BC или может ли проверка подписи GPG также выполняться с классами Java API в настоящее время? В конце концов, существует, например, класс 'java.security.Signature'. Шаги проверки не кажутся слишком сложными, поэтому я также хотел бы переписать эту функциональность. – qqilihq

Смежные вопросы