Ключевое слово в защите информации
КЛЮЧЕВОЕ СЛОВО
в защите информации
Получить ГОСТ TLS-сертификат для домена (SSL-сертификат)
Добро пожаловать, Гость! Чтобы использовать все возможности Вход или Регистрация.

Уведомление

Icon
Error

Опции
К последнему сообщению К первому непрочитанному
Offline Виталий86  
#1 Оставлено : 22 октября 2024 г. 18:51:44(UTC)
Виталий86

Статус: Новичок

Группы: Участники
Зарегистрирован: 22.10.2024(UTC)
Сообщений: 3

Сказал(а) «Спасибо»: 2 раз
Добрый день! Есть необходимость использовать подпись CAdES-BES, сгенерированную с помощью закрытого ключа, чтобы ее можно было верифицировать только с помощью соответствующего открытого ключа.
Была реализована следующая логика генерации и проверки подписи, но столкнулись с проблемой, что метод CAdESSignature.verify игнорирует переданную в него цепочку сертификатов и успешно валидирует подпись вне зависимости от того, какой открытый ключ передан и работает даже если вместо цепочки передать null.

Вопрос, реализована ли в библиотеке JCP нужная нам проверка, которая бы валидировала подпись успешно, только соответствующим открытым ключом?

override fun sign(source: String): String {
try {
val data = source.toByteArray(Charset.forName("UTF-8"))
val signerPrivateKey = privateKey as PrivateKey
val signerCert = openCertificates["OUR_PUBLIC_KEY"]!!

// Создание цепочки сертификатов подписанта из одного сертификата.
val signerCertificateChain = Collections.singletonList(signerCert)

// Создание подписи открепленного типа (detached), о чем говорит параметр true.
val cadesSignature = CAdESSignature(true)

// Добавление сертификата подписи в подпись открепленного типа.
val certHolderList: MutableList<X509CertificateHolder> = mutableListOf()
certHolderList.add(X509CertificateHolder(signerCert.encoded))
val certStore = CollectionStore(certHolderList)
cadesSignature.setCertificateStore(certStore)

// Добавление подписанта CAdES-BES.
cadesSignature.addSigner(
JCP.PROVIDER_NAME, // Имя провайдера, который будет использоваться для создания подписи.
null, // Идентификатор алгоритма хэширования, который будет использоваться для вычисления дайджеста (хэша) подписываемых данных.
JCP.GOST_SIGN_2012_512_NAME, // Идентификатор алгоритма подписи, который будет использоваться для создания электронной подписи.
signerPrivateKey, // Приватный ключ подписанта.
signerCertificateChain, // Цепочка сертификатов подписанта.
CAdESType.CAdES_BES, // Тип CAdES подписи.
null, // Адрес TSA службы.
false, // Заверяющая ли подпись.
null, // Таблица подписанных аттрибутов для добавления в подпись.
null, // Таблица неподписанных аттрибутов для добавления в подпись.
null, // CRL (списков отзыва сертификатов), связанных с подписью.
false // Добавить ли цепочку подписанта в подпись.
)

// Поток для получения сформированной подписи.
val outSignatureStream = ByteArrayOutputStream()
cadesSignature.open(outSignatureStream)

// Подпись данных.
cadesSignature.update(data)
cadesSignature.close()
outSignatureStream.close()

// CAdES-BES подпись.
val signature = outSignatureStream.toByteArray()

return Base64.getEncoder().encodeToString(signature)

} catch (e: Exception) {
logger.error("Error signing data", e)
throw Exception(e.message ?: "Ошибка при подписании данных")
}
}

override fun verify(data: String, signatureBase64: String, publicKeyAlias: String) =
try {
val source: ByteArray = data.toByteArray(Charset.forName("UTF-8"))

val byteSign = Base64.getDecoder().decode(signatureBase64)

val openCert = openCertificates[publicKeyAlias]
?: throw IllegalArgumentException("Не найден открытый ключ для systemId $publicKeyAlias")

//делаем цепочку сертификатов из одного открытого ключа
val signerCertificateChain = setOf(openCert)

val cadesSignature = CAdESSignature(
byteSign, source,
CAdESType.CAdES_BES, false
)

// cadesSignature.verify(null) //так пробовал, ничего не меняется

cadesSignature.verify(signerCertificateChain)

Pair(true, openCert.serialNumber.toString(16).uppercase())
} catch (e: Exception) {
logger.error("Произошла ошибка при проверке подписи запроса. Msg: ", e)
Pair(false, null)
}
Offline Евгений Афанасьев  
#2 Оставлено : 23 октября 2024 г. 9:58:41(UTC)
Евгений Афанасьев

Статус: Сотрудник

Группы: Участники
Зарегистрирован: 06.12.2008(UTC)
Сообщений: 3,963
Российская Федерация
Откуда: Крипто-Про

Сказал(а) «Спасибо»: 20 раз
Поблагодарили: 704 раз в 665 постах
Здравствуйте.
Тут cadesSignature.setCertificateStore(certStore) вы кладете сертификат подписи в подпись. При проверке он будет найден в самой подписи.
Offline Виталий86  
#3 Оставлено : 23 октября 2024 г. 10:10:33(UTC)
Виталий86

Статус: Новичок

Группы: Участники
Зарегистрирован: 22.10.2024(UTC)
Сообщений: 3

Сказал(а) «Спасибо»: 2 раз
Спасибо за ответ.
Правильно ли я понял, что если при генерации убрать параметр setCertificateStore, то метод проверки подписи будет работать так, как мы ожидаем, а именно возвращать true, только при использовании открытого ключа подписанта?
Offline Евгений Афанасьев  
#4 Оставлено : 23 октября 2024 г. 20:46:54(UTC)
Евгений Афанасьев

Статус: Сотрудник

Группы: Участники
Зарегистрирован: 06.12.2008(UTC)
Сообщений: 3,963
Российская Федерация
Откуда: Крипто-Про

Сказал(а) «Спасибо»: 20 раз
Поблагодарили: 704 раз в 665 постах
Да для приведенного кода.
thanks 1 пользователь поблагодарил Евгений Афанасьев за этот пост.
Виталий86 оставлено 24.10.2024(UTC)
Offline Виталий86  
#5 Оставлено : 24 октября 2024 г. 17:40:20(UTC)
Виталий86

Статус: Новичок

Группы: Участники
Зарегистрирован: 22.10.2024(UTC)
Сообщений: 3

Сказал(а) «Спасибо»: 2 раз
Понял. Еще тогда такой вопрос: есть ли возможность при получении подписи как-то средствами JCP проверить, содержит ли она в себе открытый ключ или нет?
Offline Евгений Афанасьев  
#6 Оставлено : 24 октября 2024 г. 18:24:31(UTC)
Евгений Афанасьев

Статус: Сотрудник

Группы: Участники
Зарегистрирован: 06.12.2008(UTC)
Сообщений: 3,963
Российская Федерация
Откуда: Крипто-Про

Сказал(а) «Спасибо»: 20 раз
Поблагодарили: 704 раз в 665 постах
Если это CAdES-BES или CAdES-T, то после cadesSignature = new CAdESSignature(signature, ..., ...) можно проверить состав cadesSignature.getCertificateStore().
thanks 1 пользователь поблагодарил Евгений Афанасьев за этот пост.
Виталий86 оставлено 24.10.2024(UTC)
RSS Лента  Atom Лента
Пользователи, просматривающие эту тему
Guest (2)
Быстрый переход  
Вы не можете создавать новые темы в этом форуме.
Вы не можете отвечать в этом форуме.
Вы не можете удалять Ваши сообщения в этом форуме.
Вы не можете редактировать Ваши сообщения в этом форуме.
Вы не можете создавать опросы в этом форуме.
Вы не можете голосовать в этом форуме.