Статус: Активный участник
Группы: Участники
Зарегистрирован: 23.10.2018(UTC) Сообщений: 36 Сказал(а) «Спасибо»: 4 раз
|
Добрый день, застрял с такой проблемой. Если при запуске приложения в компьютере уже установлен токен (Rutoken), то при выполнении такого вызова Security.getProvider("JCP").getServices() в списке сервисов имеется "Rutoken...." в этом плане проблем нет. Но, если при старте приложения токен не был установлен, а был установлен уже после запуска (во время работы) приложения, то тот же вызов не возвращает нужного сервиса. По всей видимости, нужно каким-то образом обновить/перечитать список. Вопрос в том - как это сделать? Погуглил проблему - ничего нужного не нашел.
|
|
|
|
Статус: Сотрудник
Группы: Участники
Зарегистрирован: 24.04.2018(UTC) Сообщений: 24 Сказал(а) «Спасибо»: 2 раз Поблагодарили: 9 раз в 6 постах
|
Добрый день! Для того, чтобы список сервисов обновлялся, вместо Security.getProvider("JCP").getServices() используйте (new JCP()).getServices().
Дело в том, что заполнение списка сервисов, поддерживаемых провайдером JCP, осуществляется при создании объекта JCP. Метод же Security.getProvider("JCP") возвращает одну и ту же запомненную копию объекта JCP, соответственно обновление списка не производится.
|
|
|
|
Статус: Активный участник
Группы: Участники
Зарегистрирован: 23.10.2018(UTC) Сообщений: 36 Сказал(а) «Спасибо»: 4 раз
|
|
|
|
|
Статус: Активный участник
Группы: Участники
Зарегистрирован: 23.10.2018(UTC) Сообщений: 36 Сказал(а) «Спасибо»: 4 раз
|
Получилось, но частично. При использовании (new JCP()).getServices() в списке появился "RutokenStore", но при дальнейшем вызове KeyStore keyStore = KeyStore.getInstance(keyStoreType, "JCP"); // keyStoreType = "RutokenStore" кидает исключение KeyStoreException RutokenStore not found Код:
java.security.KeyStoreException: RutokenStore not found
at java.security.KeyStore.getInstance(KeyStore.java:899)
at ru.monsterdev.mosregtrader.services.impl.CryptoServiceImpl.getCertificatesList(CryptoServiceImpl.java:97)
at ru.monsterdev.mosregtrader.services.impl.CryptoServiceImpl.loadCertificateList(CryptoServiceImpl.java:130)
at ru.monsterdev.mosregtrader.services.impl.CryptoServiceImpl.reloadCertificateInfos(CryptoServiceImpl.java:149)
at ru.monsterdev.mosregtrader.ui.LoginController.waitCertificateAvailable(LoginController.java:90)
at ru.monsterdev.mosregtrader.ui.LoginController.loginToMarket(LoginController.java:101)
at ru.monsterdev.mosregtrader.ui.LoginController.onLogin(LoginController.java:141)
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 sun.reflect.misc.Trampoline.invoke(MethodUtil.java:71)
at sun.reflect.GeneratedMethodAccessor28.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at sun.reflect.misc.MethodUtil.invoke(MethodUtil.java:275)
at javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1769)
at javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(FXMLLoader.java:1657)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49)
at javafx.event.Event.fireEvent(Event.java:198)
at javafx.scene.Node.fireEvent(Node.java:8411)
at javafx.scene.control.Button.fire(Button.java:185)
at com.sun.javafx.scene.control.behavior.ButtonBehavior.mouseReleased(ButtonBehavior.java:182)
at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(BehaviorSkinBase.java:96)
at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(BehaviorSkinBase.java:89)
at com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:218)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
at javafx.event.Event.fireEvent(Event.java:198)
at javafx.scene.Scene$MouseHandler.process(Scene.java:3757)
at javafx.scene.Scene$MouseHandler.access$1500(Scene.java:3485)
at javafx.scene.Scene.impl_processMouseEvent(Scene.java:1762)
at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2494)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:394)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:295)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$2(GlassViewEventHandler.java:432)
at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:410)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:431)
at com.sun.glass.ui.View.handleMouseEvent(View.java:555)
at com.sun.glass.ui.View.notifyMouse(View.java:937)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$3(WinApplication.java:177)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.security.NoSuchAlgorithmException: no such algorithm: RutokenStore for provider JCP
at sun.security.jca.GetInstance.getService(GetInstance.java:87)
at sun.security.jca.GetInstance.getInstance(GetInstance.java:206)
at java.security.Security.getImpl(Security.java:698)
at java.security.KeyStore.getInstance(KeyStore.java:896)
... 64 common frames omitted
Чего не происходит в случае, если приложение запускается с уже установленным токеном. Видимо еще что-то нужно обновить... На всякий случай приведу весь кусок кода: Код:
private static List<String> getKeyStoreTypesForProvider(Provider provider) {
List<String> result = new ArrayList<>();
for (Provider.Service service : provider.getServices()) {
if (service.getType().equals("KeyStore")) {
result.add(service.getAlgorithm());
}
}
return result;
}
try {
/* используется провайдер JCP от КриптоПРО */
Provider jcpProvider = new JCP();
// получаем список типов ключевых хранилищ, доступных через провайдер JCP
List<String> keyStoreTypes = getKeyStoreTypesForProvider(jcpProvider);
/* формируем список сертификатов, содержащихся в хранилищах */
for (String keyStoreType : keyStoreTypes) {
KeyStore keyStore = KeyStore.getInstance(keyStoreType, jcpProvider.getName()); // !!! Вот тут кидается исключение
keyStore.load(null, null);
Enumeration<String> aliases = keyStore.aliases();
while (aliases.hasMoreElements()) {
String alias = aliases.nextElement();
if (keyStore.isKeyEntry(alias)) {
java.security.cert.Certificate cert = keyStore.getCertificate(alias);
if (cert.getType().equals("X.509")) {
// какая-то логика, которая не имеет отношение к вопросу
}
}
}
}
} catch (Exception ex) {
log.error("", ex);
}
|
|
|
|
Статус: Активный участник
Группы: Участники
Зарегистрирован: 30.10.2019(UTC) Сообщений: 56 Откуда: Новосибирск Сказал(а) «Спасибо»: 14 раз
|
Столкнулся с такой же проблемой. Если рутокен вставляется в порт уже после запуска микросервиса, то KeyStore.getInstance(storeName, JCP.PROVIDER_NAME); вызывает исключение java.security.KeyStoreException: RutokenStore not found Удалось ли найти элегантное решение? Сработал пока топорный путь с удалением провайдера: Код: try {
ks = KeyStore.getInstance(storeName, JCP.PROVIDER_NAME);
} catch (KeyStoreException | NoSuchProviderException e) {
Security.removeProvider("JCP");
Security.addProvider(new ru.CryptoPro.JCP.JCP());
try {
ks = KeyStore.getInstance(storeName, JCP.PROVIDER_NAME);
} catch (KeyStoreException | NoSuchProviderException ex) {
throw new OperationException("Не удалось инициализировать в JCP хранилище " + storeName);
}
}
Отредактировано пользователем 9 октября 2020 г. 5:07:48(UTC)
| Причина: Не указана
|
|
|
|
Статус: Сотрудник
Группы: Участники
Зарегистрирован: 24.04.2018(UTC) Сообщений: 24 Сказал(а) «Спасибо»: 2 раз Поблагодарили: 9 раз в 6 постах
|
Здравствуйте! Для того, чтобы KeyStore.getInstance() отрабатывала корректно после переподключения токена, нужно ей вторым параметром передавать не имя провайдера ("JCP"), а вновь созданный объект JCP, для которого вызывалась функция getServices(): Код:
Provider jcpProvider = new JCP();
List<String> keyStoreTypes = getKeyStoreTypesForProvider(jcpProvider);
/* формируем список сертификатов, содержащихся в хранилищах */
for (String keyStoreType : keyStoreTypes) {
KeyStore keyStore = KeyStore.getInstance(keyStoreType, jcpProvider); // jcpProvider вместо jcpProvider.getName()
......
}
Похоже java хеширует у себя провайдеры по имени и если передать имя, а не провайдер, она вернет захешированную версию, в которой RutokenStore еще не было.
|
2 пользователей поблагодарили Elvira Borodina за этот пост.
|
|
|
Статус: Новичок
Группы: Участники
Зарегистрирован: 06.09.2023(UTC) Сообщений: 2
|
Может кому пригодиться. Код:
private boolean isRutokenConnect = false; // на true меняется когда работает
if (!checkStatusCard()) {
log.error("Rutoken is not connected");
throw new LoadKeystoreException("Подключите рутокен");
}
if (!isRutokenConnect) {
Security.removeProvider("JCP");
Security.addProvider(new ru.CryptoPro.JCP.JCP());
}
private boolean checkStatusCard() throws CardException {
TerminalFactory factory = TerminalFactory.getDefault();
List<CardTerminal> terminals = factory.terminals().list();
return !terminals.isEmpty();
}
|
|
|
|
Быстрый переход
Вы не можете создавать новые темы в этом форуме.
Вы не можете отвечать в этом форуме.
Вы не можете удалять Ваши сообщения в этом форуме.
Вы не можете редактировать Ваши сообщения в этом форуме.
Вы не можете создавать опросы в этом форуме.
Вы не можете голосовать в этом форуме.
Important Information:
The Форум КриптоПро uses cookies. By continuing to browse this site, you are agreeing to our use of cookies.
More Details
Close