Я следую за созданием и проверкой цифровой подписи. Подписанные данные остаются постоянными во всех прогонах, но отдельная огибаемая подпись меняется при каждом запуске. Как один и тот же текст генерирует разные отдельные прикрепленные подписи?
Чтобы ответить на комментарии...
Существует две основные причины, по которым подписи одних и тех же данных одним и тем же личным ключом могут различаться.
Некоторые алгоритмы подписи, прежде всего DSA и ECDSA, явно основывают создание подписи на случайно выбранном значении k. Эта "случайность" требуется, энтропия, секретность и уникальность значения случайной сигнатуры k критически важны. Это настолько важно, что нарушение любого из этих трех требований может выявить весь закрытый ключ для злоумышленника. Используя одно и то же значение дважды (даже при сохранении секретности k), используя предсказуемое значение или утечку даже нескольких бит k в каждой из нескольких подписей, достаточно разбить алгоритм. Требование может быть выполнено фактически случайным k или ak, построенным детерминированным способом, который также гарантирует энтропию, секретность и уникальность, ср. RFC 6967.
Однако OP ссылается на код, который использует RSA. Этот алгоритм не требует такого случайного параметра (даже если схемы заполнения могут включать случайность).
Другая причина изменений заключается в том, что подписанные данные включают в себя не только данные документа.
Когда речь идет о "подписях", часто люди не просто означают вывод байтового байта процесса подписки, а вместо этого контейнер подписи в соответствии со стандартом CMS.
В таком контейнере может быть несколько отдельных подписей, и каждый из них может иметь несколько неподписанных или подписанных атрибутов. Как видно из названия "подписанные атрибуты", вычисление значения подписи включает и эти атрибуты.
Очень часто эти подписанные атрибуты включают время подписания. Поскольку время подписи обычно изменяется в разных прогонах подписи, также меняется значение фактической подписи.
OP использует контейнеры подписи CMS. Таким образом, скорее всего, это причина, по которой сигнатуры OP различаются.
ContentSigner sha1Signer = new JcaContentSignerBuilder("SHA1withRSA").setProvider("BC").build(privKey);
который используется для генерацииJcaSignerInfoGeneratorBuilder
который, в свою очередь, добавляется вCMSSignedDataGenerator
.