|
1c Проверка сертификата на закрытый ключ в коде | ☑ | ||
|---|---|---|---|---|
|
0
Ravil45
28.04.26
✎
08:42
|
Здравствуйте, в 1с реализую автоматическую отправку через директ банк платёжные поручения. Поставил код для проверки сертификата на контейнер, подписывая его предварительно(проверка перед отправкой). Но оно работает долго, иногда быстро, но это редко(несмотря на количество документов). Может у кого есть код на проверку побыстрее. Ключи хранятся в криптоПро.
Свой код прилагаю: Процедура АвтоПодписаниеБанка() Экспорт ОтключитьОбработчикОжидания("АвтоПодписаниеБанка"); Если ПолучитьЗначениеКонстантыИспользоватьАвтоподписаниеБанкаНаСервере() Тогда Попытка СписокДокументов = ДО_СерверДиректБанк.ПолучитьСписокДокументовДляОтправкиВБанкПоДиректБанку(); //СписокДокументов = Новый Массив();//Временно СписокДокументовНаОтправку = Новый Массив(); Для Каждого ДокументПлатежки Из СписокДокументов Цикл Если ПроверкаСертификатаНаДоступность(ДокументПлатежки) Тогда //Если Ждать ПроверкаСертификатаНаДоступность(ДокументПлатежки) Тогда СписокДокументовНаОтправку.Добавить(ДокументПлатежки); КонецЕсли; КонецЦикла; Для Каждого ДокПлатежа Из СписокДокументовНаОтправку Цикл МассивОдногоДока = Новый Массив; МассивОдногоДока.Добавить(ДокПлатежа); итс_ОбщийМодульСервер.СогласоватьДокумент(МассивОдногоДока); ОбменСБанкамиКлиент.СформироватьПодписатьОтправитьЭД(МассивОдногоДока); КонецЦикла; Исключение итс_ОбщийМодульСервер.ИТСЗаписатьОшибкуВЖурнал(ОписаниеОшибки()); КонецПопытки; //На каждые 120 секунд ПодключитьОбработчикОжидания("АвтоПодписаниеБанка", 30); КонецЕсли; КонецПроцедуры &НаКлиенте //Асинх Функция ПроверкаСертификатаНаДоступность(ДокументПлатежки) Экспорт Функция ПроверкаСертификатаНаДоступность(ДокументПлатежки) Экспорт ДанныеСертификата = итс_ОбщийМодульСервер.ПолучениеДанныхСертификатаИзОбменаСБанком(ДокументПлатежки); Если ЗначениеЗаполнено(ДанныеСертификата) Тогда Сертификат = итс_ОбщийМодульСервер.ПолучениеСертификатаИзОбменаСБанком(ДокументПлатежки); КриптоСертификат = Новый СертификатКриптографии(ДанныеСертификата); //Доступен = Ждать ПроверитьНаличиеТокенаФизически(КриптоСертификат,Сертификат); Доступен = ПроверитьНаличиеТокенаФизически(КриптоСертификат,Сертификат); Возврат Доступен; Иначе Возврат Ложь; КонецЕсли; //Возврат Истина; КонецФункции Функция ПроверитьНаличиеТокенаФизически(КриптоСертификат,Сертификат) Менеджер = Новый МенеджерКриптографии("", "", 80); // Параметры по умолчанию ТекстДляПроверки = ПолучитьДвоичныеДанныеИзСтроки("Тест"); Менеджер.ПарольДоступаКЗакрытомуКлючу = ПроверкаСертификатаНаПарольНаСервере(Сертификат); //Менеджер.ИспользованиеИнтерактивногоРежима = ИспользованиеИнтерактивногоРежимаКриптографии.Использовать; Попытка // Пытаемся подписать данные. Если токена нет — упадет в Исключение Результат = Менеджер.Подписать(ТекстДляПроверки, КриптоСертификат,""); Текст = "Токен на месте " + "по сертификату " + Сертификат; Сообщить(Текст); Возврат Истина; Исключение Текст = "Токен недоступен " + "по сертификату " + Сертификат; Сообщить(Текст); Возврат Ложь; КонецПопытки; КонецФункции |
|||
|
1
MWWRuza
гуру
28.04.26
✎
14:40
|
Не знаю, может пригодится, задача похожая, но это в моей конфе на 7.7:
Функция ПроверитьНаличиеКлюча:Функция ПроверитьНаличиеКлюча()
Путь = КаталогВременныхФайлов();
Если ФС.СуществуетФайл(Путь + "ProvTocens.bat") = 0 Тогда
Тхт = СоздатьОбъект("Текст");
Тхт.ДобавитьСтроку("@ECHO OFF");
Тхт.ДобавитьСтроку("chcp 1251>NUL");
Тхт.ДобавитьСтроку("set x=Проверяем наличие ключа с КЭП Не закрывайте это окно!");
Тхт.ДобавитьСтроку("title %x%");
Тхт.ДобавитьСтроку("chcp 866>NUL");
Тхт.ДобавитьСтроку("echo %x%");
Тхт.ДобавитьСтроку("chcp 1251>NUL");
Тхт.ДобавитьСтроку("%~d0");
Тхт.ДобавитьСтроку("cd %~dp0");
Тхт.ДобавитьСтроку("""C:\Program Files\Crypto Pro\CSP\csptest.exe"" -keyset -enum_cont -verifycontext -fqcn -machinekeys >RezProvCont.txt");
Тхт.ДобавитьСтроку("""C:\Program Files\Crypto Pro\CSP\csptest.exe"" -certkey -nochange -store my -provtype 0 -verbose >RezProvSafe.txt");
Тхт.Записать(Путь + "ProvTocens.bat");
КонецЕсли;
КомандаСистемы(Путь + "ProvTocens.bat");
Если ФС.СуществуетФайл(Путь + "RezProvCont.txt") = 1 Тогда
СчСерт = 0;
Тхт = СоздатьОбъект("Текст");
Тхт.Открыть(Путь + "RezProvCont.txt");
Сч = 0;
Для Сч = 1 По Тхт.КоличествоСтрок() Цикл
ТекСтр = Тхт.ПолучитьСтроку(Сч);
Если Найти(ТекСтр, "\\.") > 0 Тогда
СчСерт = СчСерт + 1;
// Прервать;
КонецЕсли;
КонецЦикла;
Если СчСерт > 0 Тогда
CAPICOM_CURRENT_USER_STORE = 2; // 2 - Искать сертификат в ветке "Личное" хранилища.
CAPICOM_MY_STORE = "My"; // Указываем, что ветку "Личное" берем из хранилища текущего пользователя
CAPICOM_STORE_OPEN_READ_ONLY = 0; // Открыть хранилище только на чтение
oStore = СоздатьОбъект("CAPICOM.Store"); // Объект описывает хранилище сертификатов
oStore.Open(CAPICOM_CURRENT_USER_STORE, CAPICOM_MY_STORE, CAPICOM_STORE_OPEN_READ_ONLY); // Открыть хранилище сертификатов
Certs = oStore.Certificates;
Для СчСер = 1 По Certs.Count Цикл
ТекСертификат = Certs.Item(СчСер);
Отпечаток = ТекСертификат.Thumbprint;
Если СокрЛП(Отпечаток) = СокрЛП(Польз.ЭЦП.Отпечаток) Тогда
Субъект = ТекСертификат.SubjectName;
Субъект = СтрЗаменить(Субъект, ",", """,""");
Субъект = """" + Субъект + """";
СзСубъекта = СоздатьОбъект("СписокЗначений");
СзСубъекта.ИзСтрокиСРазделителями(Субъект);
ФИО = "";
ИНН = "";
СНИЛС = "";
Сч = 0;
Для Сч = 1 По СзСубъекта.РазмерСписка() Цикл
ТекСтр = СзСубъекта.ПолучитьЗначение(Сч);
ПозФИО = Найти(ТекСтр, "CN=");
Если ПозФИО > 0 Тогда
ФИО = Сред(ТекСтр, ПозФИО + 3);
КонецЕсли;
ПозИНН = Найти(ТекСтр, "ИНН=");
Если ПозИНН > 0 Тогда
ИНН = Сред(ТекСтр, ПозИНН + 4);
КонецЕсли;
ПозСНИЛС = Найти(ТекСтр, "СНИЛС=");
Если ПозСНИЛС > 0 Тогда
СНИЛС = Сред(ТекСтр, ПозСНИЛС + 6);
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецЦикла;
Если ФС.СуществуетФайл(Путь + "RezProvSafe.txt") = 1 Тогда
СзКонт = СоздатьОбъект("СписокЗначений");
Тхт = СоздатьОбъект("Текст");
Тхт.Открыть(Путь + "RezProvSafe.txt");
Сч = 0;
Для Сч = 1 По Тхт.КоличествоСтрок() Цикл
ТекСтр = Тхт.ПолучитьСтроку(Сч);
Если Найти(ТекСтр, "Cert: ") > 0 Тогда
Если (Найти(ТекСтр, ИНН) = 0) Или (Найти(ТекСтр, СНИЛС) = 0) Или (Найти(ТекСтр, ФИО) = 0) Тогда
Сч = Сч + 1;
Продолжить;
КонецЕсли;
КонецЕсли;
ПозКонт = Найти(ТекСтр, "Cont:");
Если ПозКонт > 0 Тогда
Контейнер = Сред(ТекСтр, ПозКонт + 5);
Контейнер = СтрЗаменить(Контейнер, "\", """,""");
Контейнер = """" + Контейнер + """";
СзКонт.ИзСтрокиСРазделителями(Контейнер);
КонецЕсли;
КонецЦикла;
Если СзКонт.РазмерСписка() > 0 Тогда
ИмяКонтейнера = СокрЛП(СзКонт.ПолучитьЗначение(СзКонт.РазмерСписка()));
Иначе
ДостКлюча = 0;
Возврат 0;
КонецЕсли;
Иначе
ДостКлюча = 0;
Возврат 0;
КонецЕсли;
Тхт = СоздатьОбъект("Текст");
Тхт.Открыть(Путь + "RezProvCont.txt");
Найд = 0;
Сч = 0;
Для Сч = 1 По Тхт.КоличествоСтрок() Цикл
ТекСтр = Тхт.ПолучитьСтроку(Сч);
Если Найти(ТекСтр, ИмяКонтейнера) > 0 Тогда
Найд = Найд + 1;
КонецЕсли;
КонецЦикла;
Если Найд > 0 Тогда
ДостКлюча = 1;
Иначе
ДостКлюча = 0;
КонецЕсли;
Иначе
ДостКлюча = 0;
КонецЕсли;
Иначе
ДостКлюча = 0;
КонецЕсли;
ФС.УдалитьФайл(Путь + "ProvTocens.bat");
ФС.УдалитьФайл(Путь + "RezProvCont.txt");
ФС.УдалитьФайл(Путь + "RezProvSafe.txt");
Форма.Обновить();
КонецФункцииЭто правда не совсем средствами 1С, а с помощью утилиты из КриптоПро - csptest.exe, но в моем случае, куда деваться... Функция вызывается при открытии формы обработки, в которой используется эта КЭП: ![]() Сама по себе эта обработка уже не актуальна, ДинТокен уже ни кому не нужен, у ЦРПТ новая фишка - ТСПИоТ, но пока в конфе это есть, и функция проверки наличия ключа рабочая... |
| Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |