Использование средств подписи Crypto Pro из Java

Скачайте Java CSP с официального сайта и установите.

Для разработки подписи на стороне клиента необходимо использовать подписи формата CAdES-BES (более подробно мехнизм прописан в Руководстве программиста в SDK Java CSP Крипто Про)

Необходима библиотека CAdES.jar, которая имеет несколько зависимостей:

  • установленный КриптоПро JavaCSP
  • зависимость от библиотек bouncycastle версии jdk15on-1.60: bcpkix-jdk15on-1.60.jar и cprov-jdk15on-1.60.jar
  • зависимость от библиотеки AdES-core.jar

Перед установкой CAdES.jar рекомендуется скопировать в папку, куда производится установка, библиотеки bouncycastle и AdES-core.jar, убедившись, что КриптоПро JavaCSP установлен.

Импорт ключа

Чтение сертификата ключа проверки электронной подписи из файла и запись его на носитель осуществляется при помощи команды -import утилиты keytool, которой в качестве параметров передаются:

  • уникальное имя ключа электронной подписи на носителе, в соответствии с которым на носитель записывается сертификат: -alias myKey
  • тип провайдера (КриптоПро JavaCSP): -provider ru.CryptoPro.JCSP.JCSP
  • пароль на ключ электронной подписи: -keypass 11111111
  • имя ключевого носителя (жесткий диск): -storetype HDIMAGE
  • путь к хранилищу доверенных сертификатов (в данном случае не требуется): -keystore NONE
  • пароль на хранилище доверенных сертификатов (в данном случае любой): -storepass 1
  • путь к файлу для чтения из него сертификата: -file c:\myKeyCert.cer

В случае использования Java-машин версии 11 и выше:

keytool -J-Dkeytool.compat=true -J-Duse.cert.stub=true -providerpath C:\jcp25\lib\JCSP.jar;
C:\jcp25\lib\JCP.jar;C:\jcp25\lib\ASN1P.jar;C:\jcp25\lib\asn1rt.jar;C:\jcp25\lib\forms_rt.jar
-import -alias myKey -provider ru.CryptoPro.JCSP.JCSP -keypass 11111111 -storetype HDIMAGE
-keystore NONE -storepass 1 -file c:\myKeyCert.cer

В случае использования Java-машин версии 1.8:

keytool -J-Dkeytool.compat=true -J-Duse.cert.stub=true -import -alias myKey -provider
ru.CryptoPro.JCSP.JCSP -keypass 11111111 -storetype HDIMAGE -keystore NONE -storepass 1 -file
c:\myKeyCert.cer

Пример создания CAdES-BES подписи

  • Выполняем настройки
System.setProperty("com.sun.security.enableCRLDP", "true");
System.setProperty("com.ibm.security.enableCRLDP", "true");
Security.setProperty("ocsp.enable", "true");
  • Получаем закрытый ключ и сертификаты
KeyStore keyStore = KeyStore.getInstance("HDImageStore", "JCSP");
keyStore.load(null, keyStorePassword);
PrivateKey privateKey = keyStore.getKey(keyStoreAlias, keyStorePassword);
X509Certificate cert = keyStore.getCertificate(keyStoreAlias);

Alias и Password задаются при импорте сертификатов, механизм описан выше

  • Получаем цепочки сертификатов подписи
List<X509Certificate> chain = List.Of(cert);
  • Создаем отсоединенную CAdES подпись.
CAdESSignature cadesSignature = new CAdESSignature(true);
  • Получаем Digest OID и Public Key OID в зависимоcти от типа алгоритма полученного из privateKey
String algorithm = privateKey.getAlgorithm();

Digest OID может быть JCP.GOST_DIGEST_2012_256_OID, JCP.GOST_DIGEST_2012_512_OID, JCP.GOST_DIGEST_OID

Public Key один из OID JCP.GOST_PARAMS_SIG_2012_256_KEY_OID,JCP.GOST_PARAMS_SIG_2012_512_KEY_OID,JCP.GOST_EL_DH_OID

  • Добавляем CAdES-BES подпись
cadesSignature.addSigner("JCSP", digestOid, publicKeyOid , privateKey, chain, CAdESType.CAdES_BES, null, false);
  • Данные для подписи (дайжест) в виде массива

Дайжест формируется на стороне банка и отдается клиенту.

byte[] data = ...;
  • Формируем подпись
ByteArrayOutputStream signatureStream = new ByteArrayOutputStream(); // Будущая подпись в виде массива
cadesSignature.open(signatureStream); // Подготовка контекста
cadesSignature.update(data); // Вычисление хэш-кода
cadesSignature.close(); // Создание подписи с выводом в signatureStream
signatureStream.close();
  • Получаем подпись в виде байт-массива
byte[] cadesCms = signatureStream.toByteArray();
  • Получаем подпись в строковом формате
String sign = Base64.getEncoder().encodeToString(cadesCms):