Имя: Пароль:
1C
 
Работа с документами по API "Честный знак"
0 stans
 
27.08.25
16:04
Добрый день. Кто-то сталкивался с проблемой, когда от честного знака приходит ответ "Подпись не соответствует формату CMS". Подписываю через CAdESCOM. Если все сделать через Крипто АРМ, то запрос проходит успешно. Если делаю через CAdESCOM, начало MIIW..., через Крипто АРМ начало MIAG... Уже всю голову сломал. Через плагин браузера результат то же, что и у меня через компоненту CAdESCOM.
1 MWWRuza
 
гуру
27.08.25
22:56
Если чем-то поможет(под 77 правда, но работает, там все равно вставки на скриптах jscript, так, что - не принципиально):
Код функции подписи CAPYCOM/CAdESCOM
// на основе https://infostart.ru/public/156973/
// Пар = 0 подписываем CAPICOM подпись прикрепленная, Пар = 1 подписываем CAdESCOM, подпись открепленная
Функция ПодписатьФайл(ИмяФайла, ВыбСертификат, ИмяВыхФайла, Пар = 0) Экспорт
	Если ВыбСертификат = "" Тогда
		Сообщить("В хранилище сертификатов отсутствует выбранный сертификат!");
		Возврат 0;
	КонецЕсли;
	Попытка
		JS=СоздатьОбъект("MSScriptControl.ScriptControl");
		JS.Language="jscript";
		JS.Timeout=-1;
	Исключение
		ТекстОшибки=ОписаниеОшибки();
		Сообщить("Не удалось создать объект MSScriptControl.ScriptControl","!");
		Сообщить("Описание ошибки: "+ТекстОшибки,"!");
		Возврат 0;
	КонецПопытки;
	Попытка
		Если Пар = 0 Тогда
			СтрКода="function SignFile(FileName,Cert,OutFileName)
			|{
			|   InStream=new ActiveXObject(""ADODB.Stream"");
			|   InStream.Type=1; // binary data
			|   InStream.Mode=3; // read/write
			|   InStream.Open();
			|   InStream.LoadFromFile(FileName);
			|   InData=InStream.Read(-1);
			|
			|   Signer=new ActiveXObject(""CAPICOM.Signer"");
			|   Signer.Certificate=Cert;
			|   Signer.Options=2; // CAPICOM_CERTIFICATE_INCLUDE_END_ENTITY_ONLY
			|   SignedData=new ActiveXObject(""CAPICOM.SignedData"");
			|   SignedData.Content=InData;
			|   OutSignedData=SignedData.Sign(Signer,0,0);
			|
			|   OutStream=new ActiveXObject(""ADODB.Stream"");
			|   OutStream.CharSet=""utf-8"";
			|   OutStream.Type=2; // text data
			|   OutStream.Mode=3; // read/write
			|   OutStream.Open();
			|   OutStream.WriteText(OutSignedData);
			|   OutStream.SaveToFile(OutFileName,2);
			|   OutStream.Close();
			|
			| return(0);
			|}
			|"; 
		Иначе
			// Sign(Signer,0,1) - проба открепленной ЭЦП
			СтрКода="function SignFile(FileName,Cert,OutFileName)
			|{
			|   InStream=new ActiveXObject(""ADODB.Stream"");
			|   InStream.Type=1; // binary data
			|   InStream.Mode=3; // read/write
			|   InStream.Open();
			|   InStream.LoadFromFile(FileName);
			|   InData=InStream.Read(-1);
			|
			|   Signer=new ActiveXObject(""CAdESCOM.CpSigner"");
			|   Signer.Certificate=Cert;
			|   Signer.Options=2; // CAPICOM_CERTIFICATE_INCLUDE_END_ENTITY_ONLY
			|   SignedData=new ActiveXObject(""CAdESCOM.CadesSignedData"");
			|
			|
			|   SignedData.Content=InData;
			|   OutSignedData=SignedData.SignCades(Signer,1,1,0); // параметр 3 - открепленная/прикрепленная(1 - открепленная), пар 4 - кодировка(0 - Base64)
		//	|   OutSignedData=SignedData.SignCades(Signer,1,1,0); // параметр 3 - открепленная/прикрепленная(1 - открепленная), пар 4 - кодировка(0 - Base64)
			|   OutStream=new ActiveXObject(""ADODB.Stream"");
			|   OutStream.Type=2; // text data
		//	|   OutStream.CharSet=""US-ASCII"";
			|   OutStream.CharSet=""utf-8"";
			|   OutStream.Mode=3; // read/write
			|   OutStream.Open();
			|   OutStream.WriteText(OutSignedData);
			|   OutStream.SaveToFile(OutFileName,2);
			|   OutStream.Close();
			|
			| return(0);
			|}
			|"; 
		КонецЕсли;	
		JS.AddCode(СтрКода);
		Рез = JS.Modules("Global").CodeObject.SignFile(ИмяФайла,ВыбСертификат,ИмяВыхФайла);
	Исключение
		ТекстОшибки=ОписаниеОшибки();
		Сообщить("Произошла ошибка при подписи файла!","!");
		Сообщить("Описание ошибки: "+ТекстОшибки,"!");
		Возврат 0;
	КонецПопытки;
	Возврат 1;
КонецФункции

2 stans
 
28.08.25
08:03
Спасибо. Пробовал так тоже, выдает "Подпись не соответствует формату CMS"
3 MWWRuza
 
гуру
28.08.25
09:39
(0) начало MIIW..., через Крипто АРМ начало MIAG...

У меня так:


Еще раз - все работает.
Такого - "Подпись не соответствует формату CMS" не видел ни разу, ни в процессе написания/отладки, ни при эксплуатации.

PS А, да... Еще не забудте, что нужно убрать из файла переносы строк, на выходе должна быть одна длинная строка.
Я так сделал:
УбратьПереносыСтрок()
// УбратьПереносыСтрок(ПутьКСертификату)
//
// Параметры: 
//  ПутьКСертификату - путь к файлу или текст сертификата КЭП
//
// Возвращаемое значение:
//  public_cert,signature
//
// Описание:
//  убирает переносы строк и возвращает содержимое в виде строки
//
Функция УбратьПереносыСтрок(ПутьКСертификату, Кодировка = 0)	Экспорт
	
	ВозврPublic_cert = "";
	Если (Прав(ПутьКСертификату,4) = ".cer") ИЛИ (Прав(ПутьКСертификату,4) = ".txt") ИЛИ (Прав(ПутьКСертификату,4) = ".sig") Тогда
		Если ФС.СуществуетФайл(ПутьКСертификату) = 0 Тогда
			Сообщить("Файл сертификата "+СокрЛП(ПутьКСертификату)+" не найден");
			Возврат "";
		КонецЕсли;
		АдоДБСтрим = СоздатьОбъект("ADODB.Stream");
	    АдоДБСтрим.Mode = 3;
	    АдоДБСтрим.Type = 2;//текст
		Если Кодировка = 0 Тогда
			АдоДБСтрим.charset="utf-8";
		Иначе
			АдоДБСтрим.charset="windows-1251";	
		КонецЕсли;
	    АдоДБСтрим.Open();
		АдоДБСтрим.LoadFromFile(ПутьКСертификату);
		АдоДБСтрим.Position = 0;
		ТекстСертификата = АдоДБСтрим.ReadText(-1);
		АдоДБСтрим.Close();
		Для СчСтрок = 1 По СтрКоличествоСтрок(ТекстСертификата) Цикл
			ТекСтрока = СтрПолучитьСтроку(ТекстСертификата,СчСтрок);
			Если Лев(ТекСтрока,4) = "----" Тогда
				Продолжить;
			КонецЕсли;
			ТекСтрока = СтрЗаменить(ТекСтрока,РазделительСтрок,"");
			ВозврPublic_cert = ВозврPublic_cert + ТекСтрока;
		КонецЦикла;
	Иначе
		Для СчСтрок = 1 По СтрКоличествоСтрок(ПутьКСертификату) Цикл
			ТекСтрока = СтрПолучитьСтроку(ПутьКСертификату,СчСтрок);
			Если Лев(ТекСтрока,4) = "----" Тогда
				Продолжить;
			КонецЕсли;
			ТекСтрока = СтрЗаменить(ТекСтрока,РазделительСтрок,"");
			ВозврPublic_cert = ВозврPublic_cert + ТекСтрока;
		КонецЦикла;
	КонецЕсли;

	Возврат ВозврPublic_cert;
	
КонецФункции // УбратьПереносыСтрок()


Штатными средствами 1С нормально не получается, уродуется строка, по крайней мере клюшками, по этому через поток.
Закон Брукера: Даже маленькая практика стоит большой теории.