Java — Цифровая подпись с использованием закрытого ключа для отправки данных во внешнюю веб-службу

#java #tomcat #ssl #digital-signature

#java #tomcat #ssl #цифровая подпись

Вопрос:

Мне нужно подключиться к внешнему веб-сервису из моего Java-приложения, работающего на Tomcat 6. У меня есть SSL-сертификат для моего домена, приобретенный и установленный на моем сервере. Теперь мне нужно подключиться к внешней службе и использовать закрытый ключ моего сертификата для цифровой подписи любых данных, поступающих в службу, используя хэш SHA-256 и 128-битную длину соли. Как я могу использовать закрытый ключ для создания этой подписи? Могу ли я выбрать какие-либо значения для соли? Смогут ли они расшифровать это, используя мой открытый ключ из SSL-сертификата?

Могу ли я использовать для этого библиотеку Bouncy Castle? Любой код или учебные пособия по этому вопросу были бы оценены.

Комментарии:

1. Обратите внимание, что подпись и шифрование — это не одно и то же. Если вы подпишетесь своим закрытым ключом, они смогут проверить подпись с помощью вашего открытого ключа, но шифрование не выполняется (поэтому расшифровка не производится).

Ответ №1:

Документация JCA предоставляет пример использования Signature разделе «Генерация и проверка подписи с использованием сгенерированных ключей. Вы бы использовали SHA256withRSA вместо SHA1withDSA , поскольку это поддерживается SunRsaSignProvider (при условии, что это ключ RSA). Для этого вам не понадобится BouncyCastle.

Если вы хотите использовать BouncyCastle, вам нужно будет сделать что-то в этом роде (я не пробовал этот конкретный код):

 AsymmetricKeyParameter keyParam = PrivateKeyFactory.createKey(...);
// You might need to cast to private key to RSAPrivateKey 
// and get its attributes manually here.

SHA256Digest digest = new SHA256Digest();
RSADigestSigner signer = new RSADigestSigner(digest);
signer.init(true, keyParam);
signer.update(... data to sign, start, length, ...);
byte[] signature = signer.generatedSignature();
  

(Если вы делаете это из веб-приложения, вам также потребуется, чтобы веб-приложение могло получить доступ к этому закрытому ключу, что может представлять угрозу безопасности в случае взлома веб-приложения. Возможно, стоит рассмотреть возможность использования другого ключа / сертификата, даже самоподписанного, если удаленная сторона готова его принять.)

Комментарии:

1. Удаленная сторона должна принять мой сертификат? Я пытаюсь понять, как использовать закрытый ключ из моего приобретенного SSL-сертификата для подписи этих отправляемых сообщений, но я не знаю, как получить это в моем приложении.

2. Удаленная сторона должна иметь возможность сверить вашу подпись с чем-либо: это будет открытый ключ в соответствующем сертификате, который также привязывает этот ключ к идентификатору вашего сервера. Ему нужно будет получить этот сертификат или, по крайней мере, каким-то образом узнать, с помощью какого открытого ключа проверять подпись. (Например, при использовании XML-DSig сертификат может поставляться в комплекте с подписанным сообщением.) Затем он может проверить ваш сертификат на соответствие центру сертификации, которому он доверяет.

3. Получение закрытого ключа из веб-приложения — еще одна проблема. Обычно контейнеры, подобные Tomcat, изолируют свое хранилище ключей (и свою собственную конфигурацию в целом) от веб-приложений (обычно это политика менеджера безопасности по умолчанию, когда она включена). Это позволяет помещать веб-приложения в «изолированную среду», чтобы не иметь возможности получить доступ администратора к самому контейнеру. Возможно, вы сможете отредактировать политику безопасности, чтобы разрешить веб-приложению загружать хранилище ключей, или сделать файл хранилища ключей читаемым из веб-приложения (вы даже можете передать его через JNDI). Помните, что ошибка в вашем веб-приложении может скомпрометировать ваш закрытый ключ.

4. Неясно, к какому типу веб-службы вы хотите обратиться, но вы можете захотеть взглянуть на WS-Security, как предложил @Biju Kunjummen, вместо того, чтобы создавать подпись самостоятельно. Также может представлять интерес Apache Rampart .

Ответ №2:

Я бы настоятельно рекомендовал использовать для этого стек веб-сервисов: Например. подход для клиента WS-Security с использованием Apache CXF — http://cxf.apache.org/docs/ws-security.html

Еще одна хорошая ссылка: http://www.jroller.com/gmazza/entry/cxf_x509_profile