После обновления NCALayer проблемы с подписанием XML

Добрый день,

После обновления NCALayer он для некоторых пользователей начал возвращать следующие ошибки:

{“code”:“500”,“message”:“org.apache.xml.security.signature.XMLSignatureException: kz.gov.pki.kalkan.exception.KalkanException [INVALID_PUBKEY]\nOriginal Exception was java.security.SignatureException: kz.gov.pki.kalkan.exception.KalkanException [INVALID_PUBKEY]”}

Подписывают ключом подписания физического лица. Скорее всего речь идет о kz.gov.pki.knca.commonUtils.signXml, но детали пока уточняем.

Подскажете что можно сделать?

Здравствуйте!
Ключ на токене находится? Иначе такая ошибка не может выходить.
Даже в таком случае при подписании открытый ключ из токена не запрашивается.
Нужно больше информации.

Прошу прощения, забыл уточнить что речь идет о ключах KAZTOKEN. То есть наблюдаем проблему при использовании устройств KAZTOKEN для подписания.

Пробовали подключать устройства KAZTOKEN с проблемными ключами к другим ПК, проблема повторилась.

Сколько ключей находится в токене? Ошибка при выборе конкретного ключа или любого? В логе есть что-то еще

Подчеркну что проблема не с одним токеном, таких некоторое количество.

На токенах стандартно две ключевых пары (аутентификация и подписание). Так как запрашивают подписание, то выбирать особо не из чего.

При этом на прошлой неделе (до обновления NCALayer) с теми же самыми ключами на тех же самых устройствах проблем не наблюдали.

По поводу лога информацию запросили, как получим, отпишусь.

И еще вопрос: проблемные ключи на RSA или ГОСТ?

И еще вопрос: проблемные ключи на RSA или ГОСТ?

RSA, это ключи подписания физического лица

Получили журнал, похоже на race condition, так как к NCALayer происходит несколько обращений в короткий промежуток времени:

XXXX-XX-XX 17:40:17 INFO [kz.gov.pki.api.layer.service.LogWriter] - [kz.gov.pki.osgi.layer.websocket]: Connection originated from https://XXXXXXXXXX.kz opened!
XXXX-XX-XX 17:40:17 INFO [kz.gov.pki.provider.utils.KeyStoreUtil] - DigiFlow LLP. KAZTOKEN 0 = isPresent = true
XXXX-XX-XX 17:40:17 INFO [kz.gov.pki.kalkan.pcsc.tokens.Kaztoken] - [Kaztoken]> verification… ok!
XXXX-XX-XX 17:40:17 INFO [kz.gov.pki.kalkan.pcsc.tokens.Kaztoken] - [Kaztoken]> reading map file…
XXXX-XX-XX 17:40:17 INFO [kz.gov.pki.kalkan.pcsc.tokens.Kaztoken] - [Kaztoken]> reading map file…
XXXX-XX-XX 17:40:17 INFO [kz.gov.pki.provider.utils.KeyStoreUtil] - tokenid: XXXXXXX
XXXX-XX-XX 17:40:17 INFO [kz.gov.pki.provider.utils.KeyStoreUtil] - Windows Hello for Business 1 = isPresent = true
XXXX-XX-XX 17:40:17 INFO [kz.gov.pki.kalkan.pcsc.tokens.Kaztoken] - [Kaztoken]> Get certificate
XXXX-XX-XX 17:40:17 INFO [kz.gov.pki.provider.utils.KeyStoreUtil] - DigiFlow LLP. KAZTOKEN 0 = isPresent = true
XXXX-XX-XX 17:40:17 INFO [kz.gov.pki.provider.utils.KeyStoreUtil] - Windows Hello for Business 1 = isPresent = true
XXXX-XX-XX 17:40:17 INFO [kz.gov.pki.kalkan.pcsc.tokens.Kaztoken] - [Kaztoken]> Certificate ungzipping
XXXX-XX-XX 17:40:17 INFO [kz.gov.pki.provider.utils.KeyStoreUtil] - DigiFlow LLP. KAZTOKEN 0 = isPresent = true
XXXX-XX-XX 17:40:17 INFO [kz.gov.pki.provider.utils.KeyStoreUtil] - Windows Hello for Business 1 = isPresent = true
XXXX-XX-XX 17:40:17 INFO [kz.gov.pki.kalkan.pcsc.tokens.Kaztoken] - [Kaztoken]> reading map file…
XXXX-XX-XX 17:40:17 INFO [kz.gov.pki.provider.utils.KeyStoreUtil] - DigiFlow LLP. KAZTOKEN 0 = isPresent = true
XXXX-XX-XX 17:40:17 INFO [kz.gov.pki.provider.utils.KeyStoreUtil] - Windows Hello for Business 1 = isPresent = true
XXXX-XX-XX 17:40:17 INFO [kz.gov.pki.kalkan.pcsc.tokens.Kaztoken] - [Kaztoken]> Get certificate
XXXX-XX-XX 17:40:17 INFO [kz.gov.pki.provider.utils.KeyStoreUtil] - DigiFlow LLP. KAZTOKEN 0 = isPresent = true
XXXX-XX-XX 17:40:17 INFO [kz.gov.pki.provider.utils.KeyStoreUtil] - Windows Hello for Business 1 = isPresent = true
XXXX-XX-XX 17:40:17 INFO [kz.gov.pki.provider.utils.KeyStoreUtil] - DigiFlow LLP. KAZTOKEN 0 = isPresent = true
XXXX-XX-XX 17:40:17 INFO [kz.gov.pki.provider.utils.KeyStoreUtil] - Windows Hello for Business 1 = isPresent = true
XXXX-XX-XX 17:40:17 INFO [kz.gov.pki.kalkan.pcsc.tokens.Kaztoken] - [Kaztoken]> Certificate ungzipping
XXXX-XX-XX 17:40:17 INFO [kz.gov.pki.kalkan.pcsc.tokens.Kaztoken] - [Kaztoken]> reading map file…
XXXX-XX-XX 17:40:17 INFO [kz.gov.pki.provider.utils.KeyStoreUtil] - DigiFlow LLP. KAZTOKEN 0 = isPresent = true
XXXX-XX-XX 17:40:17 INFO [kz.gov.pki.kalkan.pcsc.tokens.Kaztoken] - [Kaztoken]> Get certificate
XXXX-XX-XX 17:40:17 INFO [kz.gov.pki.kalkan.pcsc.tokens.Kaztoken] - [Kaztoken]> Certificate ungzipping
XXXX-XX-XX 17:40:17 INFO [kz.gov.pki.kalkan.pcsc.tokens.Kaztoken] - [Kaztoken]> reading map file…
XXXX-XX-XX 17:40:17 INFO [kz.gov.pki.kalkan.pcsc.tokens.Kaztoken] - [Kaztoken]> Get certificate
XXXX-XX-XX 17:40:17 INFO [kz.gov.pki.kalkan.pcsc.tokens.Kaztoken] - [Kaztoken]> Certificate ungzipping
XXXX-XX-XX 17:40:17 INFO [kz.gov.pki.api.layer.service.LogWriter] - [kz.gov.pki.osgi.layer.websocket]: Connection originated from https://XXXXXXXXXX.kz opened!
XXXX-XX-XX 17:40:17 INFO [kz.gov.pki.provider.utils.KeyStoreUtil] - DigiFlow LLP. KAZTOKEN 0 = isPresent = true
XXXX-XX-XX 17:40:17 INFO [kz.gov.pki.provider.utils.KeyStoreUtil] - tokenid: XXXXXXX
XXXX-XX-XX 17:40:17 INFO [kz.gov.pki.provider.utils.KeyStoreUtil] - Windows Hello for Business 1 = isPresent = true
XXXX-XX-XX 17:40:17 INFO [kz.gov.pki.provider.utils.KeyStoreUtil] - DigiFlow LLP. KAZTOKEN 0 = isPresent = true
XXXX-XX-XX 17:40:17 INFO [kz.gov.pki.provider.utils.KeyStoreUtil] - Windows Hello for Business 1 = isPresent = true
XXXX-XX-XX 17:40:17 INFO [kz.gov.pki.provider.utils.KeyStoreUtil] - DigiFlow LLP. KAZTOKEN 0 = isPresent = true
XXXX-XX-XX 17:40:17 INFO [kz.gov.pki.provider.utils.KeyStoreUtil] - Windows Hello for Business 1 = isPresent = true
XXXX-XX-XX 17:40:17 INFO [kz.gov.pki.provider.utils.KeyStoreUtil] - DigiFlow LLP. KAZTOKEN 0 = isPresent = true
XXXX-XX-XX 17:40:17 INFO [kz.gov.pki.provider.utils.KeyStoreUtil] - Windows Hello for Business 1 = isPresent = true
XXXX-XX-XX 17:40:17 INFO [kz.gov.pki.provider.utils.KeyStoreUtil] - DigiFlow LLP. KAZTOKEN 0 = isPresent = true
XXXX-XX-XX 17:40:17 INFO [kz.gov.pki.provider.utils.KeyStoreUtil] - Windows Hello for Business 1 = isPresent = true
XXXX-XX-XX 17:40:17 INFO [kz.gov.pki.provider.utils.KeyStoreUtil] - DigiFlow LLP. KAZTOKEN 0 = isPresent = true
XXXX-XX-XX 17:40:17 INFO [kz.gov.pki.provider.utils.KeyStoreUtil] - Windows Hello for Business 1 = isPresent = true
XXXX-XX-XX 17:40:17 INFO [kz.gov.pki.provider.utils.KeyStoreUtil] - DigiFlow LLP. KAZTOKEN 0 = isPresent = true
XXXX-XX-XX 17:40:18 INFO [kz.gov.pki.kalkan.pcsc.tokens.Kaztoken] - [Kaztoken]> verification… ok!
XXXX-XX-XX 17:40:18 INFO [kz.gov.pki.kalkan.pcsc.tokens.Kaztoken] - [Kaztoken]> verification… ok!
XXXX-XX-XX 17:40:18 INFO [kz.gov.pki.kalkan.pcsc.tokens.Kaztoken] - [Kaztoken]> reading map file…
XXXX-XX-XX 17:40:18 INFO [kz.gov.pki.kalkan.pcsc.tokens.Kaztoken] - [Kaztoken]> reading map file…
XXXX-XX-XX 17:40:18 INFO [kz.gov.pki.kalkan.pcsc.tokens.Kaztoken] - [Kaztoken]> Get certificate
XXXX-XX-XX 17:40:18 INFO [kz.gov.pki.kalkan.pcsc.tokens.Kaztoken] - [Kaztoken]> Certificate ungzipping
XXXX-XX-XX 17:40:18 INFO [kz.gov.pki.kalkan.pcsc.tokens.Kaztoken] - [Kaztoken]> RSA signing
XXXX-XX-XX 17:40:18 INFO [kz.gov.pki.kalkan.pcsc.tokens.Kaztoken] - [Kaztoken]> Get RAW RSA public key
XXXX-XX-XX 17:40:18 INFO [kz.gov.pki.api.layer.service.LogWriter] - [kz.gov.pki.osgi.layer.websocket]: Connection originated from https://XXXXXXXXXX.kz opened!
XXXX-XX-XX 17:40:18 INFO [kz.gov.pki.provider.utils.KeyStoreUtil] - DigiFlow LLP. KAZTOKEN 0 = isPresent = true
XXXX-XX-XX 17:40:18 INFO [kz.gov.pki.provider.utils.KeyStoreUtil] - tokenid: XXXXXXX
XXXX-XX-XX 17:40:18 INFO [kz.gov.pki.kalkan.pcsc.tokens.Kaztoken] - [Kaztoken]> RSA signing
XXXX-XX-XX 17:40:18 INFO [kz.gov.pki.provider.utils.KeyStoreUtil] - Windows Hello for Business 1 = isPresent = true
XXXX-XX-XX 17:40:18 INFO [kz.gov.pki.kalkan.pcsc.tokens.Kaztoken] - [Kaztoken]> Get RAW RSA public key
XXXX-XX-XX 17:40:18 INFO [kz.gov.pki.provider.utils.KeyStoreUtil] - DigiFlow LLP. KAZTOKEN 0 = isPresent = true
XXXX-XX-XX 17:40:18 INFO [kz.gov.pki.provider.utils.KeyStoreUtil] - Windows Hello for Business 1 = isPresent = true
XXXX-XX-XX 17:40:18 ERROR [kz.gov.pki.api.layer.service.LogWriter] - [kz.gov.pki.osgi.layer.common]: org.apache.xml.security.signature.XMLSignatureException: kz.gov.pki.kalkan.exception.KalkanException [INVALID_PUBKEY]
Original Exception was java.security.SignatureException: kz.gov.pki.kalkan.exception.KalkanException [INVALID_PUBKEY]:
org.apache.felix.log.LogException: kz.gov.pki.provider.exception.ProviderUtilException: org.apache.xml.security.signature.XMLSignatureException: kz.gov.pki.kalkan.exception.KalkanException [INVALID_PUBKEY]
Original Exception was java.security.SignatureException: kz.gov.pki.kalkan.exception.KalkanException [INVALID_PUBKEY]
at kz.gov.pki.provider.utils.XMLUtil.createXmlSignature(XMLUtil.java:260)
at kz.gov.pki.knca.CommonUtils.signXmls(CommonUtils.java:201)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at kz.gov.pki.knca.NCALayerCommonActivator.lambda$getModuleService$2(NCALayerCommonActivator.java:133)
at kz.gov.pki.layer.NCAWebSocketServer$NCAWebSocket.onMessage(NCAWebSocketServer.java:125)
at fi.iki.elonen.NanoWSD$WebSocket.handleWebsocketFrame(NanoWSD.java:230)
at fi.iki.elonen.NanoWSD$WebSocket.readWebsocket(NanoWSD.java:248)
at fi.iki.elonen.NanoWSD$WebSocket.access$200(NanoWSD.java:65)
at fi.iki.elonen.NanoWSD$WebSocket$1.send(NanoWSD.java:88)
at fi.iki.elonen.NanoHTTPD$HTTPSession.execute(NanoHTTPD.java:957)
at fi.iki.elonen.NanoHTTPD$ClientHandler.run(NanoHTTPD.java:192)
at java.lang.Thread.run(Thread.java:750)
Caused by: org.apache.felix.log.LogException: org.apache.xml.security.signature.XMLSignatureException: kz.gov.pki.kalkan.exception.KalkanException [INVALID_PUBKEY]
at org.apache.xml.security.algorithms.implementations.SignatureBaseRSA.engineSign(SignatureBaseRSA.java:135)
at org.apache.xml.security.algorithms.SignatureAlgorithm.sign(SignatureAlgorithm.java:174)
at org.apache.xml.security.signature.XMLSignature.sign(XMLSignature.java:628)
at kz.gov.pki.provider.utils.XMLUtil.createXmlSignature(XMLUtil.java:226)
… 14 common frames omitted
Caused by: java.security.SignatureException: kz.gov.pki.kalkan.exception.KalkanException [INVALID_PUBKEY]
at kz.gov.pki.kalkan.jce.provider.JDKDigestSignature.engineSign(JDKDigestSignature.java:160)
at java.security.Signature$Delegate.engineSign(Signature.java:1382)
at java.security.Signature.sign(Signature.java:698)
at org.apache.xml.security.algorithms.implementations.SignatureBaseRSA.engineSign(SignatureBaseRSA.java:133)
… 17 common frames omitted

Проверили те же устройства с той же командой на стенде https://kaztoken.kz/mobile-docs/, там проблем не обнаружили. Видимо специфической поведение системы вызывает сбои в NALayer.

Добрый день,

Подскажите, пожалуйста, удалось ли выявить причину описанного поведения? Стоит ли ожидать обновления NCALayer с исправлением в обозримом будущем?

Здравствуйте! Судя по логу вызывается signXmls с подписанием массива xml-строк. Если вызывать этот метод через ваш стенд, то проблемы точно нет?

Да, вызывается signXmls, на нашем стенде воспроизвести проблему не получилось, подписание двух XML завершилось успешно.

Тут как-будто две страницы параллельно открыты и параллельно подписывают.
Потому что зафиксированы два подключения.

XXXX-XX-XX 17:40:17 INFO [kz.gov.pki.api.layer.service.LogWriter] - [kz.gov.pki.osgi.layer.websocket]: Connection originated from https://XXXXXXXXXX.kz opened!

XXXX-XX-XX 17:40:18 INFO [kz.gov.pki.api.layer.service.LogWriter] - [kz.gov.pki.osgi.layer.websocket]: Connection originated from https://XXXXXXXXXX.kz opened!

На самом деле в логе подключения каждую секунду - специфика работы той системы. И вот мне тоже очень интересно не посылает ли она по двум соединениям команды? Или то, что мы видим в логе - это много соединений, но обработка одной команды?

В любом случае NCALayer должен уметь корректно справляться с ситуациями, когда к нему по разным соединениям одновременно приходят команды иначе открывается простор для поиска уязвимостей.

Добрый вечер,

Подскажите, пожалуйста, можем ли мы как-то еще помочь в локализации проблемы? Есть ли какие-нибудь новости по этому вопросу?

На всякий случай продолжу интересоваться новостями по этому вопросу.

Здравствуйте!
Полагаю проблема всё-таки в повторных вызовах из разных соединений.
Такое событие можно отловить и обработать на уровне вызовов веб-сокета, нужна доработка.
Но конкретно провайдер менять не нужно. Так как там нет изменений, порождающих эту проблему.
PS. В связи с последними заявлениями министра МЦРИАП по отмене NCALayer и ЭЦП, не направляли ли вы официальный запрос в АО НИТ? Есть ли какое-нибудь официальное пояснение?

Полагаю проблема всё-таки в повторных вызовах из разных соединений.
Такое событие можно отловить и обработать на уровне вызовов веб-сокета, нужна доработка.
Но конкретно провайдер менять не нужно. Так как там нет изменений, порождающих эту проблему.

То есть мы можем надеяться на то, что рано или поздно NCALayer будет доработан?

PS. В связи с последними заявлениями министра МЦРИАП по отмене NCALayer и ЭЦП, не направляли ли вы официальный запрос в АО НИТ? Есть ли какое-нибудь официальное пояснение?

QR подписание - это то же самое ЭЦП, причем на сертификатах НУЦ, так что ЭЦП отменять никто не планирует, на сколько я понимаю.

По поводу NCALayer, на сколько я понял заявление, тут речь идет о том, чтобы убрать поддержку NCALayer на порталах электронного правительства, а не вообще в принципе. Так как NCALayer применяется на множестве порталов в РК, то думаю что с полным отказом от него в ближайшие годы могут возникнуть серьезные проблемы.

Да, как только какое-нибудь решение опробуем, то оповестим вас для дополнительного тестирования, если можно.

Нам известны технические стороны реализации такого способа. В ознакомительных целях пробовали внедрить в NCALayer распознавание QR-кода с дальнейшим подписанием. Конечно, в этом нет практического смысла, лишь для демонстрации как это работает.

В целом сегодня получили ответы, что в ближайшее время ничего не отменяется. И, возможно, будет официальная информация на уровне АО НИТ.