Использование средств подписи 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):