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

Уведомление

Icon
Error

2 Страницы12>
Опции
К последнему сообщению К первому непрочитанному
Offline Григорий812  
#1 Оставлено : 10 августа 2021 г. 15:03:57(UTC)
Григорий812

Статус: Участник

Группы: Участники
Зарегистрирован: 05.08.2021(UTC)
Сообщений: 16
Российская Федерация
Откуда: Воронеж

Сказал(а) «Спасибо»: 1 раз
Здравствуйте.

Подскажите как можно использовать Rutoken (есть носитель с ключом) для подписи файла на смартфоне.
Разбирал примеры но остались неясными 2 момента:
1 - как просмотреть подключенный носитель с Rutoken (получить контейнеров на нем).
2 - как указать при подписи файла куда именно и под каким именем сохранить подписанный файл.

Offline Евгений Афанасьев  
#2 Оставлено : 10 августа 2021 г. 18:34:05(UTC)
Евгений Афанасьев

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

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

Сказал(а) «Спасибо»: 20 раз
Поблагодарили: 685 раз в 646 постах
Здравствуйте. На устройстве должна быть установлена панель управления рутокен из маркета. Обращение к ключу должно происходить через KeyStore.getInstance(storeType, JCSP. PROVIDER_NAME) с именем хранилища. Как получить имена хранилищ через Service класс в обьекте Provider должно быть в demo-приложении Acspclientapp. У KeyStore есть метод aliases() для перечисления контейнеров.
Offline Григорий812  
#3 Оставлено : 11 августа 2021 г. 14:19:52(UTC)
Григорий812

Статус: Участник

Группы: Участники
Зарегистрирован: 05.08.2021(UTC)
Сообщений: 16
Российская Федерация
Откуда: Воронеж

Сказал(а) «Спасибо»: 1 раз
Да панель управление установлена и токен видится, но возникла сложность с его использованием для подписи файла.


Просматриваю доступные хранилища Рутекен и их содержимое.
Код:
  //получение списка доступных хранилищ и их содержимое
    private void getAllAlias() {

        JCSP prov = new JCSP();

        String resultText = "";

        //выводим список всех хранилищ (датее интересуют только  рутокен)
        String allContent = String.valueOf(prov.getServices());
        String[] strings = allContent.split(",");
        for (int i = 0; i < strings.length; i++) {
            if(strings[i].contains("KeyStore")){
                Log.d("821", strings[i]);
                resultText = resultText + "\n" + strings[i];
            }
        }

       //получаем список алиасов контейнеров Rutoken (и HDIMAGE)
        try {
            resultText = resultText + "\n";

            String[] stores = new String [] {
                    "Aktiv Rutoken ECP NFC 2",
                    "Aktiv Rutoken ECP NFC 1",
                    "Aktiv Rutoken ECP BT 1",
                    "Aktiv Rutoken ECP BT 2",
                    "Aktiv Rutoken ECP 2",
                    "Aktiv Rutoken ECP 1",
                    "HDIMAGE",
            };

            for (int i = 0; i < stores.length; i++) {

                try {
                    resultText = resultText + "\n" + stores[i];

                    KeyStore keyStore = KeyStore.getInstance(stores[i], JCSP.PROVIDER_NAME);

                    Log.d("812", String.valueOf(keyStore));

                    keyStore.load(null, null);
                    //keyStore.getProvider();

                    //обьектов внутри
                    int size = keyStore.size();
                    resultText = resultText + "\n" + "size " + size;

                    //алиасы
                    for (Enumeration<String> aliases = keyStore.aliases(); aliases.hasMoreElements(); ) {
                        resultText = resultText + "\n" + (aliases.nextElement());
                    }

                    // закончили с текущим хранилищем
                    resultText = resultText + "\n" + " end " + stores[i];

                }catch (Exception e1){
                        Log.d("812", e1.getMessage());
                        resultText = resultText + "\n" + e1.getMessage();
                }
            }
        }catch (Exception e){
            Log.d("812", e.getMessage());
            resultText = resultText + "\n" + e.getMessage();
        }

        // выводим текст наэкран
        text.setText(resultText);
    }


Получаю, что имеется хранилище "Aktiv Rutoken ECP 1" с одним обьектом "Kab00" что соответствует истине.
Но когда далее хочу подписать данные initMySign(1) (пока хранилище и алиас на живую в код без диалогов выбора):

Код:

    private void initMySign(int useItem) {
        String alias ;
        String store ;

        if(useItem == 1 ){
            // подключенный рутоен
            alias = "Kab00";
            store = "Aktiv Rutoken ECP 1";
        }else {
            // созданный в приложении контейнер
            alias = "Test81";
            store = "HDIMAGE";
        }

          String text =  "тестовый текст";

          ContainerAdapter adapter = new ContainerAdapter(this, alias, true);
          adapter.setProviderType(ProviderType.currentProviderType());

          MySignData mySing = new MySignData (this, store, adapter, text);

            try {
                mySing.getResult(new FinalListener() {
                    @Override
                    public void onComplete() {
                        Log.d("812", " onComplete ");

                        h.post(new Runnable() {
                            @Override
                            public void run() {
                                Toast toast = Toast.makeText(getApplicationContext(), "OK", Toast.LENGTH_SHORT);
                                toast.show();
                            }
                        });
                    }
                });
            } catch (Exception e) {
                Log.d("812", e.getMessage());
            }
    }
    public class MySignData extends SignData {
        public Context  context;
        public String   store;
        public String   data;

        protected MySignData(Context _context, String _store, ContainerAdapter _adapter, String _data) {
            super(_adapter, false);
            context = _context;
            store = _store;
            data = _data;
        }
        private class SignThread extends ThreadExecuted {
            @Override
            protected void executeOne() throws Exception {
                sign();
            }
        }
        @Override
        public void getResult(FinalListener listener) throws Exception {
            SignThread thread = new SignThread();
            thread.addFinalListener(listener);
            getThreadResult(thread);
        }
        public byte[] sign() throws Exception {

            //Указываем хранилище
            KeyStoreType.init(context);
            KeyStoreType.saveCurrentType(store);

            //Тип контейнера.
            String keyStoreType = KeyStoreType.currentType();

            //Загрузка ключа и сертификата.
            load(askPinInDialog, keyStoreType,
                    containerAdapter.getClientAlias(),
                    containerAdapter.getClientPassword());


            Log.d("812", " log sign ");
            Log.d("812", String.valueOf(askPinInDialog));
            Log.d("812", String.valueOf(keyStoreType));
            Log.d("812", String.valueOf(containerAdapter.getClientAlias()));
            Log.d("812", " /log sign ");

            if (getPrivateKey() == null) {
                return null;
            }

            //Инициализация подписи
            Signature sn = Signature.getInstance(
                    algorithmSelector.getSignatureAlgorithmName(),
                    JCSP.PROVIDER_NAME);
            sn.initSign(getPrivateKey());
            sn.update(data.getBytes());

            // Формируем подпись.

            byte[] sign = sn.sign();

            return sign;
        }
    }


То onComplete() не отрабатывает - подписать данные не удается.
При этом если если запстить initMySign(0) - и использовать alias = "Test81"; store = "HDIMAGE"; (контейнер Test81 ранее был успешно создан приложении) то onComplete() отрабатывает.

Не могли бы вы подсказать в чем собственно ошибка.

Отредактировано пользователем 11 августа 2021 г. 14:28:49(UTC)  | Причина: Не указана

Offline Евгений Афанасьев  
#4 Оставлено : 11 августа 2021 г. 14:33:52(UTC)
Евгений Афанасьев

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

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

Сказал(а) «Спасибо»: 20 раз
Поблагодарили: 685 раз в 646 постах
Автор: Евгений Афанасьев Перейти к цитате
Здравствуйте. На устройстве должна быть установлена панель управления рутокен из маркета. Обращение к ключу должно происходить через KeyStore.getInstance(storeType, JCSP. PROVIDER_NAME) с именем хранилища. Как получить имена хранилищ через Service класс в обьекте Provider должно быть в demo-приложении Acspclientapp. У KeyStore есть метод aliases() для перечисления контейнеров.


Вот так можно узнать типы хранилищ:
Код:

List<String> keyStoreTypeList = new LinkedList<String>();
Set<Provider.Service> services = (new JCSP()).getServices();
// Список типов контейнеров.
for (Provider.Service service : services) {
  if (service.getType().equalsIgnoreCase("KeyStore")) {
    keyStoreTypeList.add(service.getAlgorithm());
  } // if
} // for

Далее обратиться к Rutoken согласно его имени в списке keyStoreTypeList (отфильтровать по "Rutoken" или "Aktiv"):
Код:

KeyStore keyStore = KeyStore.getInstance(storeType, JCSP.PROVIDER_NAME);
keyStore.load(null, null);
Enumeration<String> aliases = keyStore.aliases();

Или использовать для storeType имя считывателя из config.ini (их же вернет код выше):
"Aktiv Rutoken Lite SD 1"
"Aktiv Rutoken ECP 1"
"Aktiv Rutoken ECP 2"
"Aktiv Rutoken ECP BT 1"
"Aktiv Rutoken ECP BT 2"
"Aktiv Rutoken ECP NFC 1"
"Aktiv Rutoken ECP NFC 2"

Отредактировано пользователем 11 августа 2021 г. 14:35:33(UTC)  | Причина: Не указана

Offline Евгений Афанасьев  
#5 Оставлено : 11 августа 2021 г. 14:39:45(UTC)
Евгений Афанасьев

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

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

Сказал(а) «Спасибо»: 20 раз
Поблагодарили: 685 раз в 646 постах
Автор: Григорий812 Перейти к цитате
То onComplete() не отрабатывает - подписать данные не удается.

Какую ошибку получаете?

Offline Григорий812  
#6 Оставлено : 11 августа 2021 г. 16:13:08(UTC)
Григорий812

Статус: Участник

Группы: Участники
Зарегистрирован: 05.08.2021(UTC)
Сообщений: 16
Российская Федерация
Откуда: Воронеж

Сказал(а) «Спасибо»: 1 раз
Да хранилище и алиас уже есть

Автор: Григорий812 Перейти к цитате

Получаю, что имеется хранилище "Aktiv Rutoken ECP 1" с одним обьектом "Kab00" что соответствует истине.


Проблема в том что не удается подписать данные

Код:

    private void initMySign(int useItem) {
        String alias ;
        String store ;

        if(useItem == 1 ){
            // подключенный рутоен
            alias = "Kab00";
            store = "Aktiv Rutoken ECP 1";
        }else {
            // созданный в приложении контейнер
            alias = "Test81";
            store = "HDIMAGE";
        }

          String text =  "тестовый текст";

          ContainerAdapter adapter = new ContainerAdapter(this, alias, true);
          adapter.setProviderType(ProviderType.currentProviderType());

          MySignData mySing = new MySignData (this, store, adapter, text);

            try {
                mySing.getResult(new FinalListener() {
                    @Override
                    public void onComplete() {
                        Log.d("812", " onComplete ");

                        h.post(new Runnable() {
                            @Override
                            public void run() {
                                Toast toast = Toast.makeText(getApplicationContext(), "OK", Toast.LENGTH_SHORT);
                                toast.show();
                            }
                        });
                    }
                });
            } catch (Exception e) {
                Log.d("812", e.getMessage());
            }
    }
    public class MySignData extends SignData {
        public Context  context;
        public String   store;
        public String   data;

        protected MySignData(Context _context, String _store, ContainerAdapter _adapter, String _data) {
            super(_adapter, false);
            context = _context;
            store = _store;
            data = _data;
        }
        private class SignThread extends ThreadExecuted {
            @Override
            protected void executeOne() throws Exception {
                sign();
            }
        }
        @Override
        public void getResult(FinalListener listener) throws Exception {
            SignThread thread = new SignThread();
            thread.addFinalListener(listener);
            getThreadResult(thread);
        }
        public byte[] sign() throws Exception {

            //Указываем хранилище
            KeyStoreType.init(context);
            KeyStoreType.saveCurrentType(store);

            //Тип контейнера.
            String keyStoreType = KeyStoreType.currentType();

            //Загрузка ключа и сертификата.
            load(askPinInDialog, keyStoreType,
                    containerAdapter.getClientAlias(),
                    containerAdapter.getClientPassword());


            Log.d("812", " log sign ");
            Log.d("812", String.valueOf(askPinInDialog));
            Log.d("812", String.valueOf(keyStoreType));
            Log.d("812", String.valueOf(containerAdapter.getClientAlias()));
            Log.d("812", " /log sign ");

            if (getPrivateKey() == null) {
                return null;
            }

            //Инициализация подписи
            Signature sn = Signature.getInstance(
                    algorithmSelector.getSignatureAlgorithmName(),
                    JCSP.PROVIDER_NAME);
            sn.initSign(getPrivateKey());
            sn.update(data.getBytes());

            // Формируем подпись.

            byte[] sign = sn.sign();

            return sign;
        }
    }


alias = "Test81"; store = "HDIMAGE"; - контейнер созданный в саммо приложении, работает: onComplete() срабатывает .
alias = "Kab00"; store = "Aktiv Rutoken ECP 1"; - контейнер с флешки рутокена, НЕ работает (до этого в сторонеем приложении он успешно использовался).



Offline Григорий812  
#7 Оставлено : 11 августа 2021 г. 16:39:54(UTC)
Григорий812

Статус: Участник

Группы: Участники
Зарегистрирован: 05.08.2021(UTC)
Сообщений: 16
Российская Федерация
Откуда: Воронеж

Сказал(а) «Спасибо»: 1 раз
Автор: Евгений Афанасьев Перейти к цитате
Автор: Григорий812 Перейти к цитате
То onComplete() не отрабатывает - подписать данные не удается.

Какую ошибку получаете?



try catch выдал:

"java.lang.Exception: Private key or/and certificate is null."
Offline Евгений Афанасьев  
#8 Оставлено : 11 августа 2021 г. 16:51:32(UTC)
Евгений Афанасьев

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

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

Сказал(а) «Спасибо»: 20 раз
Поблагодарили: 685 раз в 646 постах
В ACSP контейнер виден, в панели?
Offline Григорий812  
#9 Оставлено : 11 августа 2021 г. 17:13:15(UTC)
Григорий812

Статус: Участник

Группы: Участники
Зарегистрирован: 05.08.2021(UTC)
Сообщений: 16
Российская Федерация
Откуда: Воронеж

Сказал(а) «Спасибо»: 1 раз
Автор: Евгений Афанасьев Перейти к цитате
В ACSP контейнер виден, в панели?


Да.

Приложение должно работать со встроенным провайдером.
Но стоящий рядом ACSP.apk контейнер видит как и сертификат в нем.
Offline Евгений Афанасьев  
#10 Оставлено : 11 августа 2021 г. 17:16:08(UTC)
Евгений Афанасьев

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

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

Сказал(а) «Спасибо»: 20 раз
Поблагодарили: 685 раз в 646 постах
В последнем релизе в ACSP в панели видно имя считывателя под именем контейнера. Проверьте, что оно тоже "Aktiv Rutoken ECP 1".
RSS Лента  Atom Лента
Пользователи, просматривающие эту тему
2 Страницы12>
Быстрый переход  
Вы не можете создавать новые темы в этом форуме.
Вы не можете отвечать в этом форуме.
Вы не можете удалять Ваши сообщения в этом форуме.
Вы не можете редактировать Ваши сообщения в этом форуме.
Вы не можете создавать опросы в этом форуме.
Вы не можете голосовать в этом форуме.