Имя: Пароль:
1C
1С v8
МенеджерКриптографии и формат выходного файла ЭЦП - ???
0 MWWRuza
 
гуру
29.10.25
15:54
Добрый день!
Вообще-то я застарелый клюшечник, но, эта тема:
Где посмотреть значение атрибута КоличествоЕдиницУпотребления (для частичного выбытия)?
как-то "сподвигла меня на подвиги" :-)))
Решил написать нечто подобное тому, что у меня в рабочей конфе семерки, для типовых 8.Х...
И даже, что-то получилось:



С самим отчетом то особых проблем не возникло, работает.
Но, для доступа в ЧЗ требуется получить токен...
На скриншоте, токен полученный в 7.7, просто вставлен в соответствующее поле.
Алгоритм его получения мне понятен и в 7.7 я его успешно использую, а тут столкнулся с проблемой подписания строки данных.
В 7.7 я использую джава-скрипты и CadesCom... Все давно и успешно работает.
Думал, что в восьмерке будет проще - всетаки для работы с ЭЦП есть встроенные штатные объекты.
А оказалось - фигвам...
В принципе, получение нужного сертификата из хранилища винды, и само подписание - я освоил, и даже как-то работает.
НО!!! На выходе получается ЭЦП "не в том формате", как нужно ЧЗ... И ни какими параметрами изменить это не получается...

Сам фрагмент модуля:
&НаКлиенте
Функция ПодписатьСтроку(СтрокаДляПодписи, СертификатЭЦП, ТекстОшибки = "", Кодировка = "CESU-8") Экспорт
	ТекстОшибки = "";
	ИмяВремФайла = ПолучитьИмяВременногоФайла();
	Текст = Новый ЗаписьТекста(ИмяВремФайла, Кодировка);
	Текст.Записать(СтрокаДляПодписи);
	Текст.Закрыть();
	ИмяМодуля				= "Crypto-Pro GOST R 34.10-2012 Cryptographic Service Provider";
	ТипМодуля				= 80;
	ПутьМодуля				= "";
	МенеджерКриптографии 	= Новый МенеджерКриптографии(ИмяМодуля, ПутьМодуля, ТипМодуля);
	АлгоритмПодписи 		= "GR 34.10-2012 256";
	АлгоритмХеширования	 = "GR 34.11-2012 256"; 
	МенеджерКриптографии.АлгоритмПодписи 		= АлгоритмПодписи;
	МенеджерКриптографии.АлгоритмХеширования	= АлгоритмХеширования;
	ИмВых		= СтрЗаменить(ИмяВремФайла, ".tmp", ".sig");
	ТипПодп 	= ПолТипПодписи();
	Попытка
		Результат =  МенеджерКриптографии.Подписать(ИмяВремФайла, ИмВых, СертификатЭЦП, ТипПодп);
		ЧтениеТекста = Новый ЧтениеТекста;  
		ЧтениеТекста.Открыть(ИмВых);  
		Подп = ЧтениеТекста.Прочитать();  
		ЧтениеТекста.Закрыть();  
	Исключение
		ТекстОшибки = ОписаниеОшибки();
	КонецПопытки;
	Попытка
		УдалитьФайлы(ИмяВремФайла);
		УдалитьФайлы(ИмВых);
	Исключение
	КонецПопытки;
	Возврат Подп;
КонецФункции // ПодписатьСтроку()

&НаКлиенте
Процедура ВыполнитьПослеВыбора(ИндВыбСтр, Пар2) Экспорт
	ИндМассСерт	= ИндВыбСтр;
	ВыбрСерт 	= СпСерт.Получить(ИндМассСерт);
	СтрИНН 		= СокрЛП(ИНН); 
	
	ПодпИНН		= ПодписатьСтроку(СтрИНН, ВыбрСерт);


КонецПроцедуры


На выходе получаю:



В семерке так:



Формат явно другой...
Но, что самое интересное - если оба файла сохранить и проверить ЭЦП с помощью "Инструментов КриптоПро", то подпись валидная! :-)))
Но, боюсь, что ЧЗ в таком виде ее не примет...
Как получить ЭЦП в правильном формате?

PS Похоже, в 7.7 ДжаваСкрипт возвращает ЭЦП в Basa64... А тут, просто бинарник... Можно попробовать закодировать готовый результат в Basa64... Но, чувствую, что есть какие-то другие решения... Использовать всякие БСП и прочее, не хочется... Уж слишком там заморочено все, не та задача.
1 timurhv
 
30.10.25
00:16
Для типовых лучше вклиниться в:
Оповещение = Новый ОписаниеОповещения("ОбработатьСообщения_ПриЗавершенииОперацииПодписи", ЭтотОбъект);
ОбменДаннымиИСМПКлиент.Подписать(*)
Плюс дополнить
ОбменДаннымиИСМПКлиент.ПодписатьЗавершение

Либо скопировать в свой общий модуль и сделать по аналогии без параметров лишних.


Для самописок без БСП в документации True API:
"Пример получения токена при авторизации с прикрепленной подписью / подписание документов с открепленной подписью на 1С"
2 timurhv
 
30.10.25
00:20
+ "CESU-8" может из-за этого ошибка отображения
3 MWWRuza
 
гуру
30.10.25
02:20
(1) Ага...
Это видел:
"Для самописок без БСП в документации True API:
"Пример получения токена при авторизации с прикрепленной подписью / подписание документов с открепленной подписью на 1С""
Но, это по сути то-же самое, что у меня в 7.7 - через CADESCOM, просто там из-за некоторых ограничений приходится Java скрипты использовать, тут можно напрямую с данными работать...
Если совсем не получится со штатным объектом "МенеджерКриптографии", то конечно переделаю на CADESCOM, не проблема... Если в клюшках заставил работать через него, тут тем более должно получиться. Но, как-то странно штатный объект работает.
Может в этом проблема - "// ТекстДляПодписи должен быть в Base64"...
Как-то я про это не подумал, подписываю строку ИНН, а там, как я подумал не критично, так, как только цифры... Но, х.з., надо попробовать...
4 MWWRuza
 
гуру
30.10.25
02:45
Попробовал перед подписанием закодировать ИНН в Basa64... Да, конечно это получается далеко не строка цифр.
Но, на выходе подпись в таком-же формате...
ЧЗ не понимает такой формат, проверил.
Сам запрос токена отрабатывает, если ему подсунуть правильную ЭЦП из файла, токен прилетает.
И если закодировать готовую ЭЦП после МенеджераКриптографии в Basa64, файл становится визуально похожим на правильный, но ЧЗ с ним 403 возвращает, подпись не валидна...
5 ProxyInspector
 
30.10.25
08:07
Сталкивался, когда
ЗаписьТекста(ИмяВремФайла, Кодировка) добавляет BOM в файл.
Создай файл в блокноте со строкой ИНН, посмотри размер. Потом  через ЗаписьТекста() с этой же строкой. Вероятнее всего размер будет другой.
6 ProxyInspector
 
30.10.25
08:15
Я писал:   https://fastcode.im/Templates/8636/zapis-teksta-bez-bom

//Запись без BOM. Размер файла 32 байта    
    ЗаписатьBOM = Ложь;
    ДвоичныеДанныеСтроки = ПолучитьДвоичныеДанныеИзСтроки(Стр, КодировкаТекста.UTF8, ЗаписатьBOM);    
    ДвоичныеДанныеСтроки.Записать(ИмяФайла);
7 arsik
 
гуру
30.10.25
08:57
(0) Может так?
	Попытка
		Результат =  МенеджерКриптографии.Подписать(ИмяВремФайла, ИмВых, СертификатЭЦП, ТипПодп);
		Подп = Base64Строка(Новый ДвоичныеДанные(ИмВых));
	Исключение
		ТекстОшибки = ОписаниеОшибки();
	КонецПопытки;

а лучше так
	Попытка
		Подп =  Base64Строка(МенеджерКриптографии.Подписать(ИмяВремФайла, Неопределено, СертификатЭЦП, ТипПодп));
	Исключение
		ТекстОшибки = ОписаниеОшибки();
	КонецПопытки;
8 MWWRuza
 
гуру
30.10.25
11:59
(7) Попробую...
Но, дело в том, что МенеджерКриптографии ничего не возвращает...
Подпись пишется во второй параметр, файл (ИмВых), в результате - "Неопределено"... Поэтому преобразовывать так - "Подп =  Base64Строка(МенеджерКриптографии.Под******", ИМХО без толку...
9 arsik
 
гуру
30.10.25
13:30
(8) Неправильно я мануал прочитал
Вот так правильно
ПодписьДвоичныеДанные = Неопределено;
Результат = МенеджерКриптографии.Подписать(ИмяВремФайла, ПодписьДвоичныеДанные, СертификатЭЦП, ТипПодп);
Подп =  Base64Строка(ПодписьДвоичныеДанные);


PS: Снова перечитал описание метода нехера не понял.

Попробуй еще вот так
Подп =  Base64Строка(МенеджерКриптографии.Подписать(ИмяВремФайла,, СертификатЭЦП, ТипПодп));

и еще вот так
Подп =  Base64Строка(МенеджерКриптографии.Подписать(ИмяВремФайла, СертификатЭЦП, ТипПодп));

Ну или через ПодписатьАсинх, там хоть в мануале четко указано в каких случаях двоичные данные возвращаются.
10 MWWRuza
 
гуру
30.10.25
13:31
А... Возможно... Даже похоже на правду :-)
Ща от текучки освобожусь - проверю.
Отпишусь потом.
11 arsik
 
гуру
30.10.25
13:35
+(9) Судя по БСП правильный вариант самый последний. В мануале ошибка
Подп =  Base64Строка(МенеджерКриптографии.Подписать(ИмяВремФайла, СертификатЭЦП, ТипПодп));
12 MWWRuza
 
гуру
30.10.25
16:31
(11) Да вот фиг там :-(
Выдает ошибку - не соответствие типа параметр 3.

Так отрабатывает:

Подп =  Base64Строка(МенеджерКриптографии.Подписать(ИмяВремФайла, Неопределено, СертификатЭЦП, ТипПодп));

И даже визуально нечто похожее на правильную возвращается, но ЧЗ ее не переваривает - запрос токена ошибку 403 возвращает с такой ЭЦП, типа доступ по такой ЭЦП запрещен...
13 MWWRuza
 
гуру
30.10.25
15:30
Попробовать перед подписанием строку ИНН в Basa64 закодировать?
14 MWWRuza
 
гуру
30.10.25
16:52
Двоичные данные до преобразования
30 82 14 39 06 09 2A 86 48 86 F7 0D 01 07 02 A0 82 14 2A 30 82 14 26 02 01 01 31 0E 30 0C 06 08 2A 85 03 07 01 01 02 02 05 00 30 0B 06 09 2A 86 48 86 F7 0D 01 07 01 A0 82 10 39 30 82 07 C2 30 82 07 6F A0 03 02 01 02 02 0B 00 CB 7F ED E5 00 00 00 00 0A 08 30 0A 06 08 2A 85 03 07 01 01 03 02 30 82 01 3B 31 21 30 1F 06 09 2A 86 48 86 F7 0D 01 09 01 16 12 64 69 74 40 64 69 67 69 74 61 6C 2E 67 6F 76 2E 72 75 31 0B 30 09 06 03 55 04 06 13 02 52 55 31 18 30 16 06 03 55 04 08 0C 0F 37 37 20 D0 9C D0 BE D1 81 D0 BA D0 B2 D0 B0 31 19 30 17 06 03 55 04 07 0C 10 D0 B3 2E 20 D0 9C D0 BE D1 81 D0 BA D0 B2 D0 B0 31 53 30 51 06 03 55 04 09 0C 4A D0 9F D1 80 D0 B5 D1 81 D0 BD D0 B5 D0 BD D1 81 D0 BA D0 B0 D1 8F 20 D0 BD D0 B0 D0 B1 D0 B5 D1 80 D0 B5 D0 B6 D0 BD D0 B0 D1 8F...

Похоже на правду...

А это в Basa64
"MIIUOQYJKoZIhvcNAQcCoIIUKjCCFCYCAQExDjAMBggqhQMHAQECAgUAMAsGCSqG
SIb3DQEHAaCCEDkwggfCMIIHb6ADAgECAgsAy3/t5QAAAAAKCDAKBggqhQMHAQED
AjCCATsxITAfBgkqhkiG9w0BCQEWEmRpdEBkaWdpdGFsLmdvdi5ydTELMAkGA1UE
BhMCUlUxGDAWBgNVBAgMDzc3INCc0L7RgdC60LLQsDEZMBcGA1UEBwwQ0LMuINCc
0L7RgdC60LLQsDFTMFEGA1UECQxK0J/RgNC10YHQvdC10L3RgdC60LDRjyDQvdCw
0LHQtdGA0LXQttC90LDRjywg0LTQvtC8IDEwLCDRgdGC0YDQvtC10L3QuNC1IDIx
JjAkBgNVBAoMHdCc0LjQvdGG0LjRhNGA0Ysg0KDQvtGB0YHQuNC4MRgwFgYFKoUD
ZAESDTEwNDc3MDIwMjY3MDExFTATBgUqhQNkBBIKNzcxMDQ3NDM3NTEmMCQGA1UE
Awwd0JzQuNC90YbQuNGE0YDRiyDQoNC+0YHRgdC40LgwHhcNMjQxMDEwMTAwNTU5
WhcNMzkxMDEwMTAwNTU5WjCCATQxFTATBgUqhQNkBBIKNDAyOTAxNzk4MTEbMBkG
CSqGSIb3DQEJARYMY2FAYXN0cmFsLnJ1MRgwFgYFKoUDZAESDTEwMjQwMDE0MzQw
NDkxCzAJBgNVBAYTAlJVMS0wKwYDVQQIDCQ0MCDQmtCw0LvRg9C20YHQutCw0Y8g
0L7QsdC70LDRgdGC0YwxGTAXBgNVBAcMENCzLiDQmtCw0LvRg9Cz0LAxNzA1BgNV
BAkMLtC/0LXRgNC10YPQu9C+0Log0KLQtdGA0LXQvdC40L3RgdC60LjQuSwg0LQu
IDYxKTAnBgNVBAoMINCQ0J4gItCa0JDQm9Cj0JPQkCDQkNCh0KLQoNCQ0JsiMSkw
JwYDVQQDDCDQkNCeICLQmtCQ0JvQo9CT0JAg0JDQodCi0KDQkNCbIjBmMB8GCCqF
AwcBAQEBMBMGByqFAwICIwEGCCqFAwcBAQICA0MABED8wUC+3zmhGwF+AVReK7cl
VGq4svE4VcooTz4DBm8S0QtZM4F2jZ/lsid3Cl4QM3dWN98HWxzgMMHvK/XM8ypI
o4IETjCCBEowCwYDVR0PBAQDAgGGMB0GA1UdDgQWBBQ/m60/RZjxVkeYcOEkGZxy
GlEEUTASBgNVHRMBAf8ECDAGAQH/AgEAMCUGA1UdIAQeMBwwCAYGKoUDZHECMAgG
BiqFA2RxATAGBgRVHSAAMCsGA1UdEAQkMCKADzIwMjQxMDA4MTM0NTQwWoEPMjAy
NzEwMDgxMzQ1NDBaMFQGBSqFA2RvBEsMSSLQmtGA0LjQv9GC0L7Qn9GA0L4gQ1NQ
IiAo0LLQtdGA0YHQuNGPIDQuMCkgKNC40YHQv9C+0LvQvdC10L3QuNC1IDItQmFz
ZSkwFAYJKwYBBAGCNxQCBAcMBVN1YkNBMBIGCSsGAQQBgjcVAQQFAgMJAAkwggF9
BgNVHSMEggF0MIIBcIAUyRNYsUynYjp+0j88pucUfJ1wo4ahggFDpIIBPzCCATsx
ITAfBgkqhkiG9w0BCQEWEmRpdEBkaWdpdGFsLmdvdi5ydTELMAkGA1UEBhMCUlUx
GDAWBgNVBAgMDzc3INCc0L7RgdC60LLQsDEZMBcGA1UEBwwQ0LMuINCc0L7RgdC6
0LLQsDFTMFEGA1UECQxK0J/RgNC10YHQvdC10L3RgdC60LDRjyDQvdCw0LHQtdGA
0LXQttC90LDRjywg0LTQvtC8IDEwLCDRgdGC0YDQvtC10L3QuNC1IDIxJjAkBgNV
BAoMHdCc0LjQvdGG0LjRhNGA0Ysg0KDQvtGB0YHQuNC4MRgwFgYFKoUDZAESDTEw
NDc3MDIwMjY3MDExFTATBgUqhQNkBBIKNzcxMDQ3NDM3NTEmMCQGA1UEAwwd0JzQ
uNC90YbQuNGE0YDRiyDQoNC+0YHRgdC40LiCEQCVH6NHfGEEOq36hYYngjRCMGgG
A1UdHwRhMF8wLaAroCmGJ2h0dHA6Ly9jcmwuZ29zdXNsdWdpLnJ1L2NkcC9ndWMy
MDIyLmNybDAuoCygKoYoaHR0cDovL2NybDIuZ29zdXNsdWdpLnJ1L2NkcC9ndWMy
MDIyLmNybDBDBggrBgEFBQcBAQQ3MDUwMwYIKwYBBQUHMAKGJ2h0dHA6Ly9jcmwu
Z29zdXNsdWdpLnJ1L2NkcC9ndWMyMDIyLmNydDCB9QYFKoUDZHAEgeswgegMNNCf
0JDQmtCcIMKr0JrRgNC40L/RgtC+0J/RgNC+IEhTTcK7INCy0LXRgNGB0LjQuCAy
LjAMQ9Cf0JDQmiDCq9CT0L7Qu9C+0LLQvdC+0Lkg0YPQtNC+0YHRgtC+0LLQtdGA
0Y/RjtGJ0LjQuSDRhtC10L3RgtGAwrsMNdCX0LDQutC70Y7Rh9C10L3QuNC1IOKE
liAxNDkvMy8yLzIvMjMg0L7RgiAwMi4wMy4yMDE4DDTQl9Cw0LrQu9GO0YfQtdC9
0LjQtSDihJYgMTQ5LzcvNi00NDkg0L7RgiAzMC4xMi4yMDIxMAwGBSqFA2RyBAMC
AQEwCgYIKoUDBwEBAwIDQQAxuqB7sycrup5BTzCaa67wbTmCpGUZduPvy72OYPzG
+ZahXlrGYo3MVICu0ADy/b297E4He/mFNMSnbccWKR/TMIIIbzCCCBygAwIBAgIR
Cfx4ggAYs2SoTEde39j/nEMwCgYIKoUDBwEBAwIwggE0MRUwEwYFKoUDZAQSCjQw
MjkwMTc5ODExGzAZBgkqhkiG9w0BCQEWDGNhQGFzdHJhbC5ydTEYMBYGBSqFA2QB
Eg0xMDI0MDAxNDM0MDQ5MQswCQYDVQQGEwJSVTEtMCsGA1UECAwkNDAg0JrQsNC7
0YPQttGB0LrQsNGPINC+0LHQu9Cw0YHRgtGMMRkwFwYDVQQHDBDQsy4g0JrQsNC7
0YPQs9CwMTcwNQYDVQQJDC7Qv9C10YDQtdGD0LvQvtC6INCi0LXRgNC10L3QuNC9
0YHQutC40LksINC0LiA2MSkwJwYDVQQKDCDQkNCeICLQmtCQ0JvQo9CT0JAg0JDQ
odCi0KDQkNCbIjEpMCcGA1UEAwwg0JDQniAi0JrQkNCb0KPQk9CQINCQ0KHQotCg
0JDQmyIwHhcNMjUwNzEyMDc0NTAyWhcNMjYwNzEyMDc1NTAyWjCB7jEcMBoGCSqG
SIb3DQEJARYNbV93X3dAbWFpbC5ydTEaMBgGCCqFAwOBAwEBEgw1MDc1MDAwOTE5
NzIxFjAUBgUqhQNkAxILMDM2OTQ5NzU5MTQxNjA0BgNVBCoMLdCS0LvQsNC00LjR
gdC70LDQsiDQktC70LDQtNC40YHQu9Cw0LLQvtCy0LjRhzEZMBcGA1UEBAwQ0JzQ
tdC00LLQtdC00LXQsjFHMEUGA1UEAww+0JzQtdC00LLQtdC00LXQsiDQktC70LDQ
tNC40YHQu9Cw0LIg0JLQu9Cw0LTQuNGB0LvQsNCy0L7QstC40YcwZjAfBggqhQMH
AQEBATATBgcqhQMCAiMBBggqhQMHAQECAgNDAARAd9bJ7zl7HQdUog4McwF+Ba79
cnMAK6E7aUZlLuggTVU2FzHWRxtq9JW4uyveAhK9y7HocXL+qZkYflmU1H2HDqOC
BUMwggU/MA4GA1UdDwEB/wQEAwID+DAmBgNVHSUEHzAdBgcqhQMFARwCBggrBgEF
BQcDAgYIKwYBBQUHAwQwKwYFKoUDZG8EIgwg0KHQmtCX0JggItCg0KPQotCe0JrQ
ldCdINCt0KbQnyIwDAYFKoUDZHIEAwIBADA0BgkrBgEEAYI3FQcEJzAlBh0qhQMC
AjIBCcGAOYTu/geE6YImg73QcIOzNYHffgIBAQIBADAyBgkrBgEEAYI3FQoEJTAj
MAkGByqFAwUBHAIwCgYIKwYBBQUHAwIwCgYIKwYBBQUHAwQwgYUGCCsGAQUFBwEB
BHkwdzA4BggrBgEFBQcwAYYsaHR0cDovL29jc3Aua2V5ZGlzay5ydS9vY3NwLWNw
LTIwMjQvb2NzcC5zcmYwOwYIKwYBBQUHMAKGL2h0dHA6Ly9kcC5rZXlkaXNrLnJ1
L3Jvb3QvY3AvYXN0cmFsLWNwLTIwMjQuY2VyMB0GA1UdIAQWMBQwCAYGKoUDZHEB
MAgGBiqFA2RxAjArBgNVHRAEJDAigA8yMDI1MDcxMjA3NDUwMlqBDzIwMjYwNzEy
MDc0NTAyWjCCAWkGBSqFA2RwBIIBXjCCAVoMUtCh0JrQl9CYICLQmtGA0LjQv9GC
0L7Qn9GA0L4gQ1NQIiAo0LLQtdGA0YHQuNGPIDQuMCkgKNC40YHQv9C+0LvQvdC1
0L3QuNC1IDItQmFzZSkMgbvQn9GA0L7Qs9GA0LDQvNC80L3Qvi3QsNC/0L/QsNGA
0LDRgtC90YvQuSDQutC+0LzQv9C70LXQutGBIMKr0KPQtNC+0YHRgtC+0LLQtdGA
0Y/RjtGJ0LjQuSDRhtC10L3RgtGAIMKr0JrRgNC40L/RgtC+0J/RgNC+INCj0KbC
uyDQstC10YDRgdC40LggMi4wwrsgKNCy0LDRgNC40LDQvdGCINC40YHQv9C+0LvQ
vdC10L3QuNGPIDUpDCfQodCkLzEyNC00NzEyINC+0YIgMTUg0Y/QvdCy0LDRgNGP
IDIwMjQMHdCh0KQvMTI4LTQyNzAg0L7RgiAxMy4wNy4yMDIyMIGEBgNVHR8EfTB7
MDigNqA0hjJodHRwOi8vd3d3LmRwLmtleWRpc2sucnUvY2RwL2NwL2FzdHJhbC1j
cC0yMDI0LmNybDA/oD2gO4Y5aHR0cDovL3d3dy5kcC10ZW5kZXIua2V5ZGlzay5y
dS9jZHAvY3AvYXN0cmFsLWNwLTIwMjQuY3JsMIIBdwYDVR0jBIIBbjCCAWqAFD+b
rT9FmPFWR5hw4SQZnHIaUQRRoYIBQ6SCAT8wggE7MSEwHwYJKoZIhvcNAQkBFhJk
aXRAZGlnaXRhbC5nb3YucnUxCzAJBgNVBAYTAlJVMRgwFgYDVQQIDA83NyDQnNC+
0YHQutCy0LAxGTAXBgNVBAcMENCzLiDQnNC+0YHQutCy0LAxUzBRBgNVBAkMStCf
0YDQtdGB0L3QtdC90YHQutCw0Y8g0L3QsNCx0LXRgNC10LbQvdCw0Y8sINC00L7Q
vCAxMCwg0YHRgtGA0L7QtdC90LjQtSAyMSYwJAYDVQQKDB3QnNC40L3RhtC40YTR
gNGLINCg0L7RgdGB0LjQuDEYMBYGBSqFA2QBEg0xMDQ3NzAyMDI2NzAxMRUwEwYF
KoUDZAQSCjc3MTA0NzQzNzUxJjAkBgNVBAMMHdCc0LjQvdGG0LjRhNGA0Ysg0KDQ
vtGB0YHQuNC4ggsAy3/t5QAAAAAKCDAdBgNVHQ4EFgQUOD8lBLK2gHEW4qcT+EAJ
ReMFEI4wCgYIKoUDBwEBAwIDQQA6rwZsrY49IrOSBvqKB6WEoHIpYbnV7Rt0C6na
2PhbPi42NqHenAfLjB5BqksDRdZXiIF70ifMM5SHetPp1qiqMYIDxTCCA8ECAQEw
ggFLMIIBNDEVMBMGBSqFA2QEEgo0MDI5MDE3OTgxMRswGQYJKoZIhvcNAQkBFgxj
YUBhc3RyYWwucnUxGDAWBgUqhQNkARINMTAyNDAwMTQzNDA0OTELMAkGA1UEBhMC
UlUxLTArBgNVBAgMJDQwINCa0LDQu9GD0LbRgdC60LDRjyDQvtCx0LvQsNGB0YLR
jDEZMBcGA1UEBwwQ0LMuINCa0LDQu9GD0LPQsDE3MDUGA1UECQwu0L/QtdGA0LXR
g9C70L7QuiDQotC10YDQtdC90LjQvdGB0LrQuNC5LCDQtC4gNjEpMCcGA1UECgwg
0JDQniAi0JrQkNCb0KPQk9CQINCQ0KHQotCg0JDQmyIxKTAnBgNVBAMMINCQ0J4g
ItCa0JDQm9Cj0JPQkCDQkNCh0KLQoNCQ0JsiAhEJ/HiCABizZKhMR17f2P+cQzAM
BggqhQMHAQECAgUAoIICDzAYBgkqhkiG9w0BCQMxCwYJKoZIhvcNAQcBMBwGCSqG
SIb3DQEJBTEPFw0yNTEwMzAxMzQyMjVaMC8GCSqGSIb3DQEJBDEiBCCtGOAXmdAq
n0dWUNMotfg8EkU5s/Rk7zNPR0wFDraG+TCCAaIGCyqGSIb3DQEJEAIvMYIBkTCC
AY0wggGJMIIBhTAKBggqhQMHAQECAgQghT65OSe4vi6iocij5YkGptdQ4wS+ouaP
pxB/2GeGYi0wggFTMIIBPKSCATgwggE0MRUwEwYFKoUDZAQSCjQwMjkwMTc5ODEx
GzAZBgkqhkiG9w0BCQEWDGNhQGFzdHJhbC5ydTEYMBYGBSqFA2QBEg0xMDI0MDAx
NDM0MDQ5MQswCQYDVQQGEwJSVTEtMCsGA1UECAwkNDAg0JrQsNC70YPQttGB0LrQ
sNGPINC+0LHQu9Cw0YHRgtGMMRkwFwYDVQQHDBDQsy4g0JrQsNC70YPQs9CwMTcw
NQYDVQQJDC7Qv9C10YDQtdGD0LvQvtC6INCi0LXRgNC10L3QuNC90YHQutC40Lks
INC0LiA2MSkwJwYDVQQKDCDQkNCeICLQmtCQ0JvQo9CT0JAg0JDQodCi0KDQkNCb
IjEpMCcGA1UEAwwg0JDQniAi0JrQkNCb0KPQk9CQINCQ0KHQotCg0JDQmyICEQn8
eIIAGLNkqExHXt/Y/5xDMAoGCCqFAwcBAQEBBECP0aqXPQFT5Xl/N4Ry2+5jNUZ5
0a8pZdypNWQIcBcIwOcrAH28iyA65kq6Fw7tZubdyisXcYcRJgIBhpdPPk+4"

А это, фрагмент рабочей ЭЦП из 1с77, по которой токен успешно прилетает:



Похоже, но не оно... Даже по начальным и конечным символам видно, да и размер другой :-(
15 MWWRuza
 
гуру
30.10.25
17:04
Хм...
Как минимум, переносы строк лишние(это на скриншоте из восьмерки):



В 7.7 у меня отдельная функция была УбратьПереносыСтрок, там вся ЭЦП одной длинной строкой...
Тут отдельными строками-блоками.
Но, все равно содержание разное, судя по началу и концу...
Не знаю, насколько это критично...
16 arsik
 
гуру
30.10.25
18:01
Вот так еще попробуй.
ВходящиеДвоичныеДанные = ПолучитьДвоичныеДанныеИзСтроки(СтрокаДляПодписи);
Подп =  Base64Строка(МенеджерКриптографии.Подписать(ВходящиеДвоичныеДанные, Неопределено, СертификатЭЦП, ТипПодп));

Будет в UTF-8 без BOM
Может у тебя реально кодировка "CESU-8" все портит

PS: Хотя, судя по скрину, одинаково.
17 timurhv
 
30.10.25
17:55
(15)
ОбщегоНазначенияИСКлиентСервер.ДвоичныеДанныеBase64(Сообщение.СвойстваПодписи.Подпись);
18 MWWRuza
 
гуру
30.10.25
18:00
(16) Сейчас попробую...

Пока, так сделал:
Подп = СтрЗаменить(Подп, Символ(10), "");
Подп = СтрЗаменить(Подп, Символ(13), "");

Переносы то убрались, ЭЦП одной строкой, но, ЧЗ не принимает ее, так-же 403...
19 MWWRuza
 
гуру
30.10.25
18:14
(16) Вот так еще попробуй.
Попробовал. Тоже отрабатывает, но, ЧЗ не принимает, 403...

(17) Хм... Интересно... Сейчас посмотрю, что она делает.
20 MWWRuza
 
гуру
30.10.25
18:31
(17) Ну, да, есть такая функция. Делает в принципе то-же самое, что у меня несколькими строками пешком было... Только проще - на вход двоичные данные из менеджера, на выходе готовый файлЭЦП в база64 и без переноса строк. Так конечно удобнее.
Но, только на результат это не влияет - все так-же ЭЦП Честному Знаку не нравится, и ошибка 403...
21 MWWRuza
 
гуру
30.10.25
18:48
Вообще, менеджер отрабатывает и с двоичными данными на входе, и с именем временного файла:

ВходящиеДвоичныеДанные = ПолучитьДвоичныеДанныеИзСтроки(СтрокаДляПодписи);
ПодпБин =  МенеджерКриптографии.Подписать(ВходящиеДвоичныеДанные, Неопределено, СертификатЭЦП, ТипПодп);
// ПодпБин =  МенеджерКриптографии.Подписать(ИмяВремФайла, Неопределено, СертификатЭЦП, ТипПодп);

Но, на результат это не влияет.
22 MWWRuza
 
гуру
30.10.25
18:53
(16) PS: Хотя, судя по скрину, одинаково.

Видишь ли... Был бы там текст, да еще на русском... Я бы еще понял. Но, там ИНН - строка цифр. По идее, кодировка тут не должна влиять.
23 MWWRuza
 
гуру
30.10.25
19:27
Я вот уже подумал... Изучая все дебри типовой, натолкнулся на такую функцию:

// Описание подключения внешней компоненты (ExtraCryptoAPI).
//
// Возвращаемое значение:
//  Структура:
//   * ПолноеИмяМакета - Строка
//   * ИмяОбъекта      - Строка
//
Функция ОписаниеКомпоненты() Экспорт
	
	Параметры = Новый Структура;
	Параметры.Вставить("ИмяОбъекта", "ExtraCryptoAPI");
	Параметры.Вставить("ПолноеИмяМакета",
		"Справочник.СертификатыКлючейЭлектроннойПодписиИШифрования.Макет.КомпонентаExtraCryptoAPI");
	Возврат Параметры;
	
КонецФункции

Может МенеджерКриптографии и не умеет нормальные ЭЦП делать, и требуется ВК "ExtraCryptoAPI" - ? Зачем он тогда вообще нужен?
24 MWWRuza
 
гуру
30.10.25
22:16
Нет... Терпение у меня конечно большое, но не безграничное...
Все, надоело "ловить черную кошку в темной комнате, когда, вполне возможно, что ее там нет :-( ".
Сделал как ЦРПТ в описании TrueAPI рекомендует, через Com объект CADESCOM...
Текст функций из описания, с небольшими правками под то, что у меня уже сделано, и все взлетело.
ИНН подписывается, правильно - токен получается, и отчет отрабатывает.
Разбираться, как это сделано в типовых через МенеджерКриптографии(???? или через ВК????) у меня сил и терпения нет... Открыв два десятка процедур/функций раскиданных по куче общих модулей, я потерял нить алгоритма...
Плюнул, 15 минут, и завел функции из описания TrueAPI... Там конечно тоже с ошибками(а как без этого, там все описание из ошибок), но, хотя-бы не сложно, да и подглядеть есть куда - в свою обкатанную временем старушку 7.7...
25 MWWRuza
 
гуру
30.10.25
22:36
Хотел еще упростить, убрать КриптоПрошную функцию получения сертификата по отпечатку, так, как у меня уже и так был сертификат как объект...
Но, нет... Типы не совпадают. 1С и тут извратилась, и сделала свой объект "Сертификат" <> сертификату из КриптоПро...
Ну, да ладно, работает и хорошо.

PS Просто "не оптимально" - я один раз получаю список сертификатов объектами 1С, для выбора нужного из списка, а потом получаю опять список сертификатов через CADESCOM, для выбора из него нужного по отпечатку, переданному из списка выбора.
Надо будет подумать и переделать, убрать первую часть с 1Совскими объектами совсем, сразу из КриптоПро получать список и выбирать. Но, это уже под настроение :-)
26 АгентБезопасной Нацио
 
31.10.25
09:50
(25) странно. получаю 1с-овский сертификат, и подписываю им через CADESCOM нормально. Через МенеджерКриптографии не мог подписать то-ли Зерно, то-ли еще что-то подобное..
27 Ёпрст
 
гуру
31.10.25
12:14
(25) мне trad  прислал свой код для чз, там тоже, серт получается через cadescom, без какого либо геммороя с менеджером криптографии
28 MWWRuza
 
гуру
31.10.25
18:06
(26) странно. получаю 1с-овский сертификат, и подписываю им через CADESCOM нормально.

Ну, х.з.... Уже в принципе не актуально, на боевую задачу это не повлияет... Но, как говорится, "истина дороже!" :-)
Вот, сертификат 1С:



А вот, сертификат КриптоПро:



Конечно у них типы разные, CADESCOM ждет COMобъект, а получает вместо этого "что-то не понятное от 1С" - "СертификатКриптографии", отсюда и ошибка несоответствия типов... Может и можно как-то преобразовать Сертификат 1С в COMобъект, который схавает CADESCOM, но оно того не стоит... Уберу при настроениии получение сертификата через МенеджерКриптографии, оставлю только CADESCOM...

(27) Вот, не жалко, тем более это код из описания TrueAPI с минимальными доработками и исправлением ошибок:
Функции подписи через CADESCOM
// sThumbprint - отпечаток сертификата, используемого для подписи; строка,
// представляющая отпечаток в шестнадцатеричном виде
// пример 195934d72dcdf69149901d6632aca4562d8806d8
// bDetached - Истина/Ложь - откреплённая(для подписания документов)/прикреплённая(для олучения токена авторизации) подпись
Функция ПодписатьТекстЦРПТ(ТекстДляПодписи, sThumbprint, bDetached)
	ВходящиеДвоичныеДанные = Base64Строка(ПолучитьДвоичныеДанныеИзСтроки(ТекстДляПодписи));
	CADESCOM_BASE64_TO_BINARY = 1; // Входные данные пришли в Base64
	CADESCOM_CADES_TYPE = 1; // Тип усовершенствованной подписи
	CAPICOM_AUTHENTICATED_ATTRIBUTE_SIGNING_TIME = 0; // Атрибут штампа времени подписи
	oSigner = Новый COMОбъект("CAdESCOM.CPSigner");
	oSigner.Certificate = ПолучитьСертификатПоОтпечатку(sThumbprint);
	oSigningTimeAttr = Новый COMОбъект("CAdESCOM.CPAttribute");
	oSigningTimeAttr.Name = CAPICOM_AUTHENTICATED_ATTRIBUTE_SIGNING_TIME;
	oSigningTimeAttr.Value = ТекущаяДата();
	oSigner.AuthenticatedAttributes2.Add(oSigningTimeAttr);
	ТекстДляПодписи = СокрЛП(ТекстДляПодписи);
	oSignedData = Новый COMОбъект("CAdESCOM.CadesSignedData");
	oSignedData.ContentEncoding = CADESCOM_BASE64_TO_BINARY;
	oSignedData.Content = ВходящиеДвоичныеДанные;
	EncodingType = 0;
	sSignedMessage = oSignedData.SignCades(oSigner, CADESCOM_CADES_TYPE, bDetached, EncodingType);
	Возврат sSignedMessage; // Подпись в формате Base64
КонецФункции

//Отпечаток - строка HEX
Функция ПолучитьСертификатПоОтпечатку(ОтпечатокСтр)
	Отпечаток = СтрЗаменить(ОтпечатокСтр, " ", "");	
	Рез 	= Неопределено; // Найденный сертификат (Com-объект)
	CAPICOM_CURRENT_USER_STORE = 2; // 2 - Искать сертификат в ветке "Личное" хранилища.
	CAPICOM_MY_STORE = "My"; // Указываем, что ветку "Личное" берем из хранилища текущего пользователя
	CAPICOM_STORE_OPEN_READ_ONLY = 0; // Открыть хранилище только на чтение
	oStore 	= Новый COMОбъект("CAdESCOM.Store");
	oStore.Open(CAPICOM_CURRENT_USER_STORE, CAPICOM_MY_STORE, CAPICOM_STORE_OPEN_READ_ONLY); // Открыть хранилище сертификатов
	Certs 	= oStore.Certificates;
	Для СчСер = 1 По Certs.Count Цикл
		ТекСертификат = Certs.Item (СчСер); 
		ТекОтпечаток  = ТекСертификат.Thumbprint; // возвращается отпечаток в шестнадцатеричном виде
		Если ВРЕГ(ТекОтпечаток) = ВРЕГ(Отпечаток) Тогда
			Рез = ТекСертификат;
			Прервать;
		КонецЕсли;
	КонецЦикла;
	oStore.Close(); // Закрыть хранилище сертификатов и освободить объект
	Возврат Рез;
КонецФункции

Вызов этого:
&НаКлиенте
Функция ПодписатьСтроку(СтрокаДляПодписи, СертификатЭЦП) Экспорт // Здесь СертификатЭЦП - сертификат полученный в 1С через МенеджерКриптографии, ИМХО - лишнее, упрощу потом...
  	Отпечаток = СертификатЭЦП.Отпечаток;	
	Подп = ПодписатьТекстЦРПТ(СтрокаДляПодписи, Отпечаток, Ложь); // третий параметр прикрепленная. Если нужно открепленная - то Истина
	Возврат Подп;
КонецФункции
Глупец, лишенный способности посмеяться над собой вместе с другими, не сможет долго выносить программирование. Фредерик Брукс-младший