Ошибка цифровой подписи - длина подписи неверна: получено 344, но ожидалось 256 - PullRequest
0 голосов
/ 14 сентября 2018

Я занимаюсь разработкой Java-класса цифровой подписи с использованием алгоритма SHA1withRSA с 256-битным сертификатом. Но я получаю эту ошибку:

Длина подписи не верна: получил 344, но ожидал 256.

Я использую провайдера SunJSSE (который не реализует алгоритм SHA256 с RSA), потому что он использует тип хранилища ключей PKCS12. И мне это нужно, потому что это пакетное приложение.

Является ли алгоритм SAH1 с RSA несовместимым с 256-битным сертификатом?

1 Ответ

0 голосов
/ 14 сентября 2018

Во-первых, вы не можете иметь 256-битный сертификат RSA или ключ.256-битный RSA не был безопасен, когда RSA был опубликован в 1977 году, и гораздо реже, в любое время.Это исключение говорит о том, что он ищет 256 байт подпись, которая составляет 2048 бит, что подразумевает ключ и сертификат также из 2048 бит, что в настоящее время (с 2015 года) является стандартным и широко используемым размером для RSA.

Во-вторых, да SHA1 с RSA технически работает с 2048-битным ключом RSA (и сертификатом) , хотя и менее безопасен.Изначально SHA1 был рассчитан только на 80-битную стойкость к коллизиям и был сломан (при значительно более низкой стоимости, около 63 бит) около года назад - см. https://shattered.io - во многих случаях он был небезопасен для подписейи, таким образом, все больше систем, программ и пользователей отклоняют подписи SHA1.Например, во всех Java-пакетах Oracle начиная с версии 8u144 (примерно прошлым летом) java.security jdk.certpath.disabledAlgorithms настроен по умолчанию, чтобы запретить использование подписанных SHA1 сертификатов в TLS (включая SSL, но SSL также не работает).и запрещено по умолчанию).Java в настоящее время не запрещает другое использование подписей SHA1, но может быть изменено на.Множество вещей, с которыми вы, возможно, захотите общаться или взаимодействовать, например, браузеры, веб-серверы, системы электронной почты, репозитории и т. Д., Либо уже запретили SHA1, либо, вероятно, захотят.

Но это не такнеобходимо. Вы можете использовать несколько провайдеров в одной программе, в частности вы можете использовать KeyStore PKCS12 из SunJSSE, в то же время используя Signature SHA256withRSA (или другие варианты SHA2 + RSA) из SunRsaSign.На самом деле проще всего вообще не указывать провайдера (-ов) и просто позволить KeyStore.getInstance() и Signature.getInstance() (и другим классам интерфейса JCA) автоматически найти правильного провайдера.

Наконец, вашподпись, вероятно, закодирована в base64: ceil (256/3) * 4 = 344.Посмотрите на данные и убедитесь, что они состоят из символов base64 и, если да, то какой набор.Если это base64, декодируйте его в двоичный файл (т. Е. byte[] в Java) и используйте его.В Java8 + просто используйте java.util.Base64, который поддерживает оба распространенных варианта: вариант «MIME» и вариант «URL-safe» (в основном JSON).В старых версиях Java вы можете использовать javax.xml.bind.DatatypeConverter для MIME или любое количество сторонних библиотек с различными возможностями.

...