Шифрование строки на основе мастер-пароля в 1С Предприятие 8.3.19

16.03.23

Разработка - Защита ПО и шифрование

Демонстрация возможностей шифрования строки на основе мастер-пароля в 1С Предприятие 8.3.19. AES без zip файла, RSA, PKDF2. (c использованием библиотеки С# через com).

Скачать файлы

Наименование Файл Версия Размер
Crypto1C.dll (библиотека для com)
.dll 12,50Kb
5
.dll 12,50Kb 5 Скачать
Crypto1C.rar ( два файла исходников C# )
.rar 3,49Kb
2
.rar 3,49Kb 2 Скачать

На эту публикацию вдохновили три момента:

  1. В 1С алгоритм шифрования AES можно использовать только через zip файл, что показалось неудобным и не совсем правильным с точки зрения безопасности.
  2. Публикация № 151246, где нашел понятный и простой шаблон для создания com библиотеки C# для работы с 1С. "Как написать COM-объект для 1С на Visual Studio C# 2008"
  3. Шифровать без использования громоздкой системы сертификатов (если нет в этом необходимости)

Тип данных входные и выходные: только строка и cтрока Base64, массив байтов в параметрах не используется. В тестовых целях константы можно заменить на реквизиты.

Константы:
1. UnlockKey (СоленыйХеш) - не хранится, он расчитывается из мПароля и соли. 
2. EncKey (основной ключ шифрования) - шифрован ключом PubKey
3. PubKey - публичный RSA
4. PrivatKey (приватный RSA)  - шифрован UnlockKey

// ********************

// Как работать с библиотекой:

// AES ШифроватьКонтрольнуюФразуСохранитьКлюч
&НаКлиенте  
Процедура ШифроватьКонтрольнуюФразуСохранитьКлюч(Команда) 
	Если Не ЗначениеЗаполнено(pass) Тогда // pass - строка
		Сообщить("контрольное слово пустое !!");
		возврат; 
	КонецЕсли;
	ВремяСтарт=ТекущаяУниверсальнаяДатаВМиллисекундах();
	ШифроватьКонтрольнуюФразуСохранитьКлючНаСервере();
	Сообщить ("Шифровка контр фразы, потрачено млсек: "+ (ТекущаяУниверсальнаяДатаВМиллисекундах()-ВремяСтарт)); 
КонецПроцедуры

// AES ШифроватьКонтрольнуюФразуСохранитьКлючНаСервере
&НаСервере  
Процедура ШифроватьКонтрольнуюФразуСохранитьКлючНаСервере() 
	
	МойОбъект = Новый COMОбъект("Crypto1C.MyClass");  
	Ответ_Com=МойОбъект.EncryptStringToBytes_Aes(pass); // генерим Key,IV сохраняем, нужны для шифрования данных в хранилище 
	если НЕ Ответ_Com.Success Тогда
		Сообщить(Ответ_Com.Message);  
		Возврат;
	КонецЕсли;  
	
	ШифрованнаяСтрока=Ответ_Com.Encrypted_64;
	Key=Ответ_Com.Key_64 ; // строка base64
	IV=Ответ_Com.IV_64 ;   // строка base64
	
	ДлинаКлючаРазмер= ПолучитьДвоичныеДанныеИзBase64Строки(Key).Размер();
	ДлинаВектораРазмер= ПолучитьДвоичныеДанныеИзBase64Строки(IV).Размер();
	ДлинаШифрованнаяСтрокаРазмер= ПолучитьДвоичныеДанныеИзBase64Строки(ШифрованнаяСтрока).Размер();
	
	ЖурналЛогов.ДобавитьСтроку("ДлинаКлюча (EncKey) байт/длина:" + ДлинаКлючаРазмер+"/"+СтрДлина(Key));
	ЖурналЛогов.ДобавитьСтроку("ДлинаВектора (IV) байт/длина: "+ДлинаВектораРазмер+"/"+СтрДлина(IV));
	ЖурналЛогов.ДобавитьСтроку("Контрольная фраза шифрованная AES байт/длина: "+ДлинаШифрованнаяСтрокаРазмер+"/"+СтрДлина(ШифрованнаяСтрока));
	ЖурналЛогов.ДобавитьСтроку("**************************************"); 

	МойОбъект = Неопределено;

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

// AES Шифровать PrivKey
&НаСервере  
Процедура ШифроватьPrivKeyСохранитьВБазе() 
	
	МойОбъект = Новый COMОбъект("Crypto1C.MyClass");  
	Ответ_Com=МойОбъект.EncryptStringToBytes_Aes(ПубличныйИПриватныйКлюч,Key,IV); ПубличныйИПриватныйКлюч = строка
	если Ответ_Com.Success Тогда
		ШифрованнаяСтрока=Ответ_Com.Data; // строка Base64
	КонецЕсли;
	
	ДлинаКлючаРазмер= ПолучитьДвоичныеДанныеИзBase64Строки(Key).Размер();
	ДлинаВектораРазмер= ПолучитьДвоичныеДанныеИзBase64Строки(IV).Размер();
	ДлинаШифрованнаяСтрокаРазмер= ПолучитьДвоичныеДанныеИзBase64Строки(ШифрованнаяСтрока).Размер();
	
	ЖурналЛогов.ДобавитьСтроку("ДлинаКлюча байт/длина:" + ДлинаКлючаРазмер+"/"+СтрДлина(Key));
	ЖурналЛогов.ДобавитьСтроку("ДлинаВектора байт/длина: "+ДлинаВектораРазмер+"/"+СтрДлина(IV));
	ЖурналЛогов.ДобавитьСтроку("ДлинаШифрованнаяСтрока байт/длина: "+ДлинаШифрованнаяСтрокаРазмер+"/"+СтрДлина(ШифрованнаяСтрока));
	
	МойОбъект = Неопределено;

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


// AES дешифровать
&НаКлиенте
Процедура Расшифровать(Команда)
  
	РасшифроватьНаСервере();
	
КонецПроцедуры

// AES дешифровать
&НаСервере
Процедура РасшифроватьНаСервере()
	МойОбъект = Новый COMОбъект("Crypto1C.MyClass");
	
	Ответ_Com=МойОбъект.DecryptStringFromBytes_Aes(ШифрованнаяСтрока,Key,IV);
	если Ответ_Com.Success Тогда
		ДешифрованнаяСтрока=Ответ_Com.DecryptedString ; // строка
	КонецЕсли;

	ЖурналЛогов.ДобавитьСтроку(ДешифрованнаяСтрока);
	МойОбъект = Неопределено;
КонецПроцедуры


// PBKDF2
&НаКлиенте
Процедура PBKDF2_ПолучитьКлючИСохранитьСоль(Команда) 
	Если Не ЗначениеЗаполнено(mPwd) Тогда // mPwd - строка
		Сообщить("mPwd пустое !!");
		возврат; 
	КонецЕсли;
	ВремяСтарт=ТекущаяУниверсальнаяДатаВМиллисекундах();
	PBKDF2_ПолучитьКлючИСохранитьСольНаСервере();
	Сообщить ("ХЕШ потрачено млсек: "+ (ТекущаяУниверсальнаяДатаВМиллисекундах()-ВремяСтарт));
КонецПроцедуры 

  // PBKDF2
&НаСервере
Процедура PBKDF2_ПолучитьКлючИСохранитьСольНаСервере()
	// PBKDF2(string pwd, int myIterations, string AlgName, out string salt_64)	
	// new HashAlgorithmName(AlgName)  
	//Asymmetric algorithms implemented using other technologies:
	//Must recognize at least "MD5", "SHA1", "SHA256", "SHA384", and "SHA512". 
	//Should recognize additional CNG identifiers for any additional hash algorithms that they support.
	//Due to collision problems with MD5 and SHA1, Microsoft recommends a security model based on SHA256 or better.
	
	МойОбъект = Новый COMОбъект("Crypto1C.MyClass");
	МойОбъектОтвет=МойОбъект.PBKDF2(mPwd, 100000, "SHA512"); //PBKDF2(mPwd, кол-во итерации, алгортим хеширования)
	UnlockKey=МойОбъектОтвет.HashPwdSalt_64; // строка Base64
	Соль=МойОбъектОтвет.Salt_64; 
	
	ЖурналЛогов.ДобавитьСтроку("Соль: "+Соль);
	ЖурналЛогов.ДобавитьСтроку("UnlockKey: "+UnlockKey); // нужен для AES шифрования PrivKey
	
	UnlockKeyРазмер= ПолучитьДвоичныеДанныеИзBase64Строки(UnlockKey).Размер();
	СольРазмер= ПолучитьДвоичныеДанныеИзBase64Строки(Соль).Размер();
	
	ЖурналЛогов.ДобавитьСтроку("Соль байт/длина: "+СольРазмер+"/"+СтрДлина(Соль)); 
	ЖурналЛогов.ДобавитьСтроку("UnlockKey (ключ для AES) байт/длина:" + UnlockKeyРазмер+"/"+СтрДлина(UnlockKey)); 
	ЖурналЛогов.ДобавитьСтроку("**************************************"); 

	МойОбъект = Неопределено;

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

&НаКлиенте
Процедура ОчиститьЖурнал(Команда)
	ЖурналЛогов.Очистить();
КонецПроцедуры

// Получить ключи RSA
&НаСервере
Процедура ПолучитьКлючи_RSA_НаСервере()
	//ОбъектКриптографии = Новый COMОбъект("System.Security.Cryptography.RSACryptoServiceProvider"); требует на входе массив байтов ((
	ОбъектКриптографии = Новый COMОбъект("Crypto1C.MyClass");
	Ответ = ОбъектКриптографии.RSAKeyGenerator();
	// Значение true, чтобы включать закрытый и открытый ключ RSA; 
	// значение false, чтобы включать только открытый ключ. 
	
	//SuccessCom=Ответ.Success;
	//MessageCom=Ответ.Message;
	//DataCom=Ответ.Data;
	
	ПубличныйКлюч=Ответ.PublicKey; // строка
	ПубличныйИПриватныйКлюч=Ответ.PrivatKey; // строка
	
	Если НЕ Ответ.Success Тогда
		Сообщить(Ответ.Message);
	КонецЕсли;
	
	ПубличныйКлючРазмер= ПолучитьДвоичныеДанныеИзСтроки(ПубличныйКлюч).Размер();
	ПубличныйИПриватныйКлючРазмер= ПолучитьДвоичныеДанныеИзСтроки(ПубличныйИПриватныйКлюч).Размер();

	ЖурналЛогов.ДобавитьСтроку("Публичный ключ : "+ПубличныйКлюч); 
	ЖурналЛогов.ДобавитьСтроку("Приватный ключ : "+ПубличныйИПриватныйКлюч);  
	
	ЖурналЛогов.ДобавитьСтроку("ПубличныйКлючРазмер байт/длина:" + ПубличныйКлючРазмер+"/"+СтрДлина(ПубличныйКлюч));
	ЖурналЛогов.ДобавитьСтроку("ПриватныйКлючРазмер байт/длина: "+ПубличныйИПриватныйКлючРазмер+"/"+СтрДлина(ПубличныйИПриватныйКлюч));
	ЖурналЛогов.ДобавитьСтроку("**************************************"); 

	ОбъектКриптографии = Неопределено;

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

&НаКлиенте
Процедура ПолучитьКлючи_RSA(Команда)
	ВремяСтарт=ТекущаяУниверсальнаяДатаВМиллисекундах();
	ПолучитьКлючи_RSA_НаСервере();  
	Сообщить ("RSA потрачено млсек: "+ (ТекущаяУниверсальнаяДатаВМиллисекундах()-ВремяСтарт));
КонецПроцедуры

// Проверка работы RSA
&НаСервере
Процедура Шифровка_RSA()
	
	Если Не ЗначениеЗаполнено(ИсхТекстСтрока) Тогда
		сообщить("ИсхТекстСтрока пустая!!");
		Возврат;
	КонецЕсли;
	
	// сом для саое шифрования
	МойОбъект = Новый COMОбъект("Crypto1C.MyClass"); 
	
	//шифруем *********************** 
	ЗашифрованныйТекстСтр=""; 
	РасшифрованныйТекстСтр=""; 

	Ответ_Com = МойОбъект.RSAEncrypt(ИсхТекстСтрока, ПубличныйКлюч, false);  
	если Ответ_Com.Success Тогда
		ЗашифрованныйТекстСтр=Ответ_Com.Encrypted_64 ; // строка base64
	КонецЕсли;
	
	ПубличныйКлючРазмер= ПолучитьДвоичныеДанныеИзСтроки(ПубличныйКлюч).Размер();
	ПубличныйИПриватныйКлючРазмер= ПолучитьДвоичныеДанныеИзСтроки(ПубличныйИПриватныйКлюч).Размер();
	ЗашифрованныйТекстСтрРазмер= ПолучитьДвоичныеДанныеИзBase64Строки(ЗашифрованныйТекстСтр).Размер();
	ИсхТекстСтрокаРазмер= ПолучитьДвоичныеДанныеИзСтроки(ИсхТекстСтрока).Размер();

	ЖурналЛогов.ДобавитьСтроку("Публичный ключ: "+ПубличныйКлюч);  
	ЖурналЛогов.ДобавитьСтроку("Приватный ключ: "+ПубличныйИПриватныйКлюч);
	ЖурналЛогов.ДобавитьСтроку("Шифрованный текст : "+ЗашифрованныйТекстСтр);
	ЖурналЛогов.ДобавитьСтроку("РасшифрованныйТекстСтр : "+РасшифрованныйТекстСтр); 
	
	ЖурналЛогов.ДобавитьСтроку("ЗашифрованныйТекстСтрРазмер байт/длина: "+ЗашифрованныйТекстСтрРазмер+"/"+СтрДлина(ЗашифрованныйТекстСтр));
	ЖурналЛогов.ДобавитьСтроку("ПубличныйКлючРазмер байт/длина:" + ПубличныйКлючРазмер+"/"+СтрДлина(ПубличныйКлюч));
	ЖурналЛогов.ДобавитьСтроку("ПубличныйИПриватныйКлючРазмер байт/длина: "+ПубличныйИПриватныйКлючРазмер+"/"+СтрДлина(ПубличныйИПриватныйКлюч));
	ЖурналЛогов.ДобавитьСтроку("ИсхТекстСтрокаРазмер байт/длина: "+ИсхТекстСтрокаРазмер+"/"+СтрДлина(ИсхТекстСтрока));

	МойОбъект = Неопределено;

	////Pass the data to ENCRYPT, the public key information 
	////(using RSACryptoServiceProvider.ExportParameters(false),
	////and a boolean flag specifying no OAEP padding.
	//encryptedData_64 = RSAEncrypt(StringToEncrypt, PublickKey_XML, false);
	//
	////Pass the data to DECRYPT, the private key information 
	////(using RSACryptoServiceProvider.ExportParameters(true),
	////and a boolean flag specifying no OAEP padding.
	//decryptedString = RSADecrypt(encryptedData_64, PrivatKey_XML, false);
	
КонецПроцедуры 

// Дешифровка RSA
&НаСервере
Процедура Дешифров_RSA()
	Если Не ЗначениеЗаполнено(ПубличныйИПриватныйКлюч) Тогда
		сообщить("ПубличныйИПриватныйКлюч пустая!!");
		Возврат;
	КонецЕсли;
	// сом для саое шифрования
	МойОбъект = Новый COMОбъект("Crypto1C.MyClass"); 
		
	//расшифруем  ******************  
	РасшифрованныйТекстСтр=""; 
	Ответ_Com = МойОбъект.RSADecrypt(ЗашифрованныйТекстСтр, ПубличныйИПриватныйКлюч, false);  
	если Ответ_Com.Success Тогда
		РасшифрованныйТекстСтр=Ответ_Com.DecryptedString ; // строка
	КонецЕсли;
	
	ПубличныйКлючРазмер= ПолучитьДвоичныеДанныеИзСтроки(ПубличныйКлюч).Размер();
	ПубличныйИПриватныйКлючРазмер= ПолучитьДвоичныеДанныеИзСтроки(ПубличныйИПриватныйКлюч).Размер();
	ЗашифрованныйТекстСтрРазмер= ПолучитьДвоичныеДанныеИзBase64Строки(ЗашифрованныйТекстСтр).Размер();
	ИсхТекстСтрокаРазмер= ПолучитьДвоичныеДанныеИзСтроки(ИсхТекстСтрока).Размер();

	ЖурналЛогов.ДобавитьСтроку("Публичный ключ: "+ПубличныйКлюч);  
	ЖурналЛогов.ДобавитьСтроку("Приватный ключ: "+ПубличныйИПриватныйКлюч);
	ЖурналЛогов.ДобавитьСтроку("Шифрованный текст : "+ЗашифрованныйТекстСтр);
	ЖурналЛогов.ДобавитьСтроку("РасшифрованныйТекстСтр : "+РасшифрованныйТекстСтр); 
	
	ЖурналЛогов.ДобавитьСтроку("ЗашифрованныйТекстСтрРазмер байт/длина: "+ЗашифрованныйТекстСтрРазмер+"/"+СтрДлина(ЗашифрованныйТекстСтр));
	ЖурналЛогов.ДобавитьСтроку("ПубличныйКлючРазмер байт/длина:" + ПубличныйКлючРазмер+"/"+СтрДлина(ПубличныйКлюч));
	ЖурналЛогов.ДобавитьСтроку("ПубличныйИПриватныйКлючРазмер байт/длина: "+ПубличныйИПриватныйКлючРазмер+"/"+СтрДлина(ПубличныйИПриватныйКлюч));
	ЖурналЛогов.ДобавитьСтроку("ИсхТекстСтрокаРазмер байт/длина: "+ИсхТекстСтрокаРазмер+"/"+СтрДлина(ИсхТекстСтрока));

	МойОбъект = Неопределено;
	
КонецПроцедуры


&НаКлиенте
Процедура Шифрование_RSA(Команда)
	Шифровка_RSA();
КонецПроцедуры    

&НаСервере
Процедура ПолучитьКлючПоСолиНаСервере()   
	СольСохранненая=ОбщийСерверныйПривилегированный.УстановитьПолучитьКонстанту("Соль",ложь,);
	UnlockKey="";
	Соль = СольСохранненая; // строка
	МойОбъект = Новый COMОбъект("Crypto1C.MyClass");
	UnlockKey=МойОбъект.PBKDF2_GetXash(mPwd, 100000, "SHA512", Соль).HashPwdSalt_64 ;
	
	ЖурналЛогов.ДобавитьСтроку("Соль: "+Соль);
	ЖурналЛогов.ДобавитьСтроку("UnlockKey: "+UnlockKey);
	
	UnlockKeyРазмер= ПолучитьДвоичныеДанныеИзBase64Строки(UnlockKey).Размер();
	СольРазмер= ПолучитьДвоичныеДанныеИзBase64Строки(Соль).Размер();
	
	ЖурналЛогов.ДобавитьСтроку("UnlockKey байт/длина:" + UnlockKeyРазмер+"/"+СтрДлина(UnlockKey)); 
	ЖурналЛогов.ДобавитьСтроку("Соль байт/длина: "+СольРазмер+"/"+СтрДлина(Соль)); 
	
	МойОбъект = Неопределено;
КонецПроцедуры

&НаКлиенте
Процедура ПолучитьКлючПоСоли(Команда)
	ПолучитьКлючПоСолиНаСервере();
КонецПроцедуры

&НаКлиенте
Процедура Дешифровка_RSA(Команда)
	Дешифров_RSA();
КонецПроцедуры

&НаСервере
Процедура ШифроватьПоКлючу_AESНаСервере() // шифруем по заданному
	
	МойОбъект = Новый COMОбъект("Crypto1C.MyClass");  
	
// 1. получить хеш по соли 
	 Соль="";
	 UnlockKey=""; 
	 СольСохраненная=ОбщийСерверныйПривилегированный.УстановитьПолучитьКонстанту("Соль",ложь,); 
	 Соль=СольСохраненная;
	 UnlockKey=МойОбъект.PBKDF2_GetXash(mPwd, 100000, "SHA512", СольСохраненная).HashPwdSalt_64 ;
	 
	 // 2. получить PrivKey по UnlockKey AES 
	 ДешифрованнаяСтрока="";
	 IV="";
	 PrivKey_шифр=ОбщийСерверныйПривилегированный.УстановитьПолучитьКонстанту("PrivKey",ложь,);
	 IV_Сохр=ОбщийСерверныйПривилегированный.УстановитьПолучитьКонстанту("IV",ложь,);
	 IV=IV_Сохр;
	 Ответ_Com=МойОбъект.DecryptStringFromBytes_Aes(PrivKey_шифр,UnlockKey,IV_Сохр); 
	 если Ответ_Com.Success Тогда
		 ПубличныйИПриватныйКлюч=Ответ_Com.DecryptedString ;
	 иначе
		 сообщить ("2.DecryptStringFromBytes_Aes: "+Ответ_Com.Message);
	 КонецЕсли;  	
	 
	 // 3. получить EncKey по PrivKey  RSA 
	 РасшифрованныйТекстСтр=""; 
	 EncKey_шифр=ОбщийСерверныйПривилегированный.УстановитьПолучитьКонстанту("EncKey",ложь,);
	 Ответ_Com = МойОбъект.RSADecrypt(EncKey_шифр, ПубличныйИПриватныйКлюч, false);  
	 если Ответ_Com.Success Тогда   
		 EncKey=Ответ_Com.DecryptedString ;
		 Key= EncKey;
	 иначе
		 сообщить ("3.RSADecrypt: "+Ответ_Com.Message);
	 КонецЕсли; 
	 
	 // 4. Шифруем Aes_ByKey
	 	Ответ_Com=МойОбъект.EncryptStringToBytes_Aes_ByKey(pass,Key,IV);
	если Ответ_Com.Success Тогда
		ШифрованнаяСтрока=Ответ_Com.Encrypted_64 ; 
	иначе
		 сообщить ("4.AesEncrypt: "+Ответ_Com.Message);
	КонецЕсли;  
	
	ДлинаКлючаРазмер= ПолучитьДвоичныеДанныеИзBase64Строки(Key).Размер();
	ДлинаВектораРазмер= ПолучитьДвоичныеДанныеИзBase64Строки(IV).Размер();
	ДлинаШифрованнаяСтрокаРазмер= ПолучитьДвоичныеДанныеИзBase64Строки(ШифрованнаяСтрока).Размер();
	
	ЖурналЛогов.ДобавитьСтроку("ДлинаКлюча байт/длина:" + ДлинаКлючаРазмер+"/"+СтрДлина(Key));
	ЖурналЛогов.ДобавитьСтроку("ДлинаВектора байт/длина: "+ДлинаВектораРазмер+"/"+СтрДлина(IV));
	ЖурналЛогов.ДобавитьСтроку("ДлинаШифрованнаяСтрока байт/длина: "+ДлинаШифрованнаяСтрокаРазмер+"/"+СтрДлина(ШифрованнаяСтрока));

	МойОбъект = Неопределено;
КонецПроцедуры

&НаКлиенте
Процедура ШифроватьПоКлючу_AES(Команда) 
	Если НЕ ЗначениеЗаполнено(mPwd)Тогда
		Сообщить ("поле mPwd пустое !!");
		Возврат;
	КонецЕсли;
	ШифроватьПоКлючу_AESНаСервере();
КонецПроцедуры

&НаСервере
Процедура ШифроватьИСохранитьКлючиНаСервере()
	
	ОбщийСерверныйПривилегированный.УстановитьПолучитьКонстанту("Соль",истина,Соль); 
	ОбщийСерверныйПривилегированный.УстановитьПолучитьКонстанту("PubKey",истина,ПубличныйКлюч); 
	ОбщийСерверныйПривилегированный.УстановитьПолучитьКонстанту("IV",истина,IV); // вектор AES хранилища  
	ОбщийСерверныйПривилегированный.УстановитьПолучитьКонстанту("КонтрольнаяФраза",истина,ШифрованнаяСтрока); // Контрольная Фраза для проверки EncKey и IV 
	
	Если НЕ ЗначениеЗаполнено(ПубличныйИПриватныйКлюч) ИЛИ НЕ ЗначениеЗаполнено(UnlockKey) ИЛИ НЕ ЗначениеЗаполнено(IV) Тогда 
		Сообщить ("не заполнены: ПубличныйИПриватныйКлюч, UnlockKey, IV" );
		возврат;
	КонецЕсли;   
	
	Если НЕ ЗначениеЗаполнено(Key) ИЛИ НЕ ЗначениеЗаполнено(ПубличныйКлюч) Тогда 
		Сообщить ("не заполнены: Key, ПубличныйКлюч" );
		возврат;
	КонецЕсли; 
	
	ШифроватьИСохранитьПриватКлюч ();
	ШифроватьИСохранитьКлючХранилища (); 	
КонецПроцедуры

&НаКлиенте
Процедура ШифроватьИСохранитьКлючи(Команда) 
	Если ПоляОчищены Тогда
		Сообщить ("операция невыполниам, все поля очищены!!"); 
		Возврат ;
	КонецЕсли;
	ВремяСтарт=ТекущаяУниверсальнаяДатаВМиллисекундах();
	ШифроватьИСохранитьКлючиНаСервере();
	Сообщить ("Шифровка ключей и запись, потрачено млсек: "+ (ТекущаяУниверсальнаяДатаВМиллисекундах()-ВремяСтарт));
КонецПроцедуры 

&НаСервере
Процедура ШифроватьИСохранитьПриватКлюч() 
	
	МойОбъект = Новый COMОбъект("Crypto1C.MyClass");  
	Ответ_Com=МойОбъект.EncryptStringToBytes_Aes_ByKey(ПубличныйИПриватныйКлюч,UnlockKey,IV); // нужен отдельный вектор IV ?
	
	если Ответ_Com.Success Тогда
		ПриватныйКлючШифрованный=Ответ_Com.Encrypted_64 ;  
	Иначе
		Сообщить (Ответ_Com.messsage);
	КонецЕсли;
	
	ОбщийСерверныйПривилегированный.УстановитьПолучитьКонстанту("PrivKey",истина,ПриватныйКлючШифрованный);// шифруется(AES)ключом UnlockKey 
	МойОбъект = Неопределено;
	
КонецПроцедуры

  &НаСервере
  Процедура ШифроватьИСохранитьКлючХранилища()
	  
	  // сом для саое шифрования
	МойОбъект = Новый COMОбъект("Crypto1C.MyClass"); 

	Ответ_Com = МойОбъект.RSAEncrypt(Key, ПубличныйКлюч, false);  
	если Ответ_Com.Success Тогда
		EncKey_Зашифрованныйр=Ответ_Com.Encrypted_64 ;
	Иначе
		Сообщить (Ответ_Com.messsage);
	КонецЕсли;
  
	ОбщийСерверныйПривилегированный.УстановитьПолучитьКонстанту("EncKey",истина,EncKey_Зашифрованныйр); // шифруется(RSA) ключом PubKey  
	EncKey_Зашифрованный_Размер= ПолучитьДвоичныеДанныеИзBase64Строки(EncKey_Зашифрованныйр).Размер();
	ЖурналЛогов.ДобавитьСтроку("EncKey_Зашифрованныйр байт/длина: "+EncKey_Зашифрованный_Размер+"/"+СтрДлина(EncKey_Зашифрованныйр));
	
	МойОбъект = Неопределено;
 КонецПроцедуры

 &НаСервере
 Процедура ПроверитьКонтрольнуюФаразуНаСервере() 
	 
	 МойОбъект = Новый COMОбъект("Crypto1C.MyClass");
	 // 1. получить хеш по соли 
	 Соль="";
	 UnlockKey=""; 
	 СольСохраненная=ОбщийСерверныйПривилегированный.УстановитьПолучитьКонстанту("Соль",ложь,); 
	 Соль=СольСохраненная;
	 UnlockKey=МойОбъект.PBKDF2_GetXash(mPwd, 100000, "SHA512", СольСохраненная).HashPwdSalt_64 ;
	 
	 // 2. получить PrivKey по UnlockKey AES 
	 ДешифрованнаяСтрока="";
	 IV="";
	 PrivKey_шифр=ОбщийСерверныйПривилегированный.УстановитьПолучитьКонстанту("PrivKey",ложь,);
	 IV_Сохр=ОбщийСерверныйПривилегированный.УстановитьПолучитьКонстанту("IV",ложь,);
	 IV=IV_Сохр;
	 Ответ_Com=МойОбъект.DecryptStringFromBytes_Aes(PrivKey_шифр,UnlockKey,IV_Сохр); 
	 если Ответ_Com.Success Тогда
		 ПубличныйИПриватныйКлюч=Ответ_Com.DecryptedString ;
	 иначе
		 сообщить ("2.DecryptStringFromBytes_Aes: "+Ответ_Com.Message);
	 КонецЕсли;  	
	 
	 // 3. получить EncKey по PrivKey  RSA 
	 РасшифрованныйТекстСтр=""; 
	 EncKey_шифр=ОбщийСерверныйПривилегированный.УстановитьПолучитьКонстанту("EncKey",ложь,);
	 Ответ_Com = МойОбъект.RSADecrypt(EncKey_шифр, ПубличныйИПриватныйКлюч, false);  
	 если Ответ_Com.Success Тогда   
		 EncKey=Ответ_Com.DecryptedString ;
		 Key= EncKey;
		 //РасшифрованныйТекстСтр = EncKey; 
	 иначе
		 сообщить ("3.RSADecrypt: "+Ответ_Com.Message);
	 КонецЕсли;
	 
	 // 4. получить исходную строку по EncKey AES
	 ДешифрованнаяСтрока=""; 
	 Фраза_шифр=ОбщийСерверныйПривилегированный.УстановитьПолучитьКонстанту("КонтрольнаяФраза",ложь,);
	 Ответ_Com=МойОбъект.DecryptStringFromBytes_Aes(Фраза_шифр,EncKey,IV);
	 если Ответ_Com.Success Тогда
		 pass=Ответ_Com.DecryptedString ; 
	 иначе
		 сообщить ("4.DecryptStringFromBytes_Aes: "+Ответ_Com.Message);
	 КонецЕсли;  	
	 
	 МойОбъект = Неопределено;
	 
 КонецПроцедуры
 
 &НаКлиенте
 Процедура ПроверитьКонтрольнуюФаразу(Команда)  
	 Если НЕ ЗначениеЗаполнено(mPwd) Тогда   
		 Сообщить ("mPwd пустое!");
		 Возврат;
	 КонецЕсли;
	 ВремяСтарт=ТекущаяУниверсальнаяДатаВМиллисекундах();
	 ПроверитьКонтрольнуюФаразуНаСервере(); 
	 Сообщить ("Проверка контрольной фразы, потрачено млсек: "+ (ТекущаяУниверсальнаяДатаВМиллисекундах()-ВремяСтарт));
 КонецПроцедуры
 
 &НаКлиенте
 Процедура ОчиститьПоляФормы(Команда)
	 ОчиститьНаСервере();
	 ПоляОчищены=Истина; 
 КонецПроцедуры 
 
 &НаСервере
Процедура ОчиститьЭлемент(рекв)
    Попытка
        ЭтаФорма[рекв].Очистить();
	Исключение 
		
	КонецПопытки; 
	
    Попытка
        ЭтаФорма[рекв] = Неопределено
	Исключение 
		
	КонецПопытки;
КонецПроцедуры

&НаСервере
Функция ОчиститьНаСервере()
	
	для Каждого рекв из ЭтаФорма.ПолучитьРеквизиты() Цикл
		
		Если рекв.имя = "Объект" Тогда
			об    = РеквизитФормыВЗначение("Объект");
			Для Каждого р Из об.Метаданные().Реквизиты Цикл
				если р.Имя <> "СтрокаДляОзвучки" тогда
					Объект[р.Имя]    = Неопределено;  
				КонецЕсли;
			КонецЦикла;
			Для Каждого р Из об.Метаданные().ТабличныеЧасти Цикл
				Объект[р.Имя].Очистить();
			КонецЦикла;
		Иначе  		
			если рекв.Имя <> "mPwd" И рекв.Имя <> "ЖурналЛогов" тогда
				ОчиститьЭлемент(рекв.имя) ; 
			КонецЕсли;
			
		КонецЕсли;
	КонецЦикла;
	
КонецФункции

// ***********************************

Библиотека работает на windows с установленной .net версии не ниже 4.0, регистрируется запуском RegAsm.exe, в директории C:\Windows\Microsoft.NET\Framework64\v4.0.30319, ключами /codebase или /unregister

Публикация сопровождается:

Библиотекой Crypto1C.dll 

Архив с двумя файлами исходников на C# Crypto1C.rar

шифрования строки на основе мастер-пароля AES без zip файла RSA PKDF2 библиотека С# через com строка cтрока Base64 массив байтов

См. также

Запрет глобального поиска в конфигурации

Защита ПО и шифрование Платформа 1С v8.3 1С:Бухгалтерия 3.0 Абонемент ($m)

Представляю вам микрорасширение, которое запрещает глобальный поиск по вашей конфигурации.

1 стартмани

09.02.2023    2225    9    aximo    4    

2

Как защитить pdf файл

Защита ПО и шифрование Абонемент ($m)

Для установки защиты pdf документа, полученного в 1С, написано консольное приложение на c#., использующее одну зависимость pdfSharp.dll. В результате работы приложения ограничены операции над документом и записаны метаданные. С помощью аргументов командной строки можно управлять работой приложения.

2 стартмани

30.01.2023    1662    1    olevlasam    3    

3

Универсальный синтаксический анализатор ASN.1 для декодирования .key, .cer, .der, .p7m, .p7s, .crt, .pem

Защита ПО и шифрование Платформа 1С v8.3 Конфигурации 1cv8 Абонемент ($m)

Универсальный синтаксический анализатор ASN.1, который может декодировать любую допустимую структуру ASN.1 DER или BER, независимо от того, закодирована ли она в кодировке Base64 (распознаются необработанные base64, защита PEM и begin-base64) или в шестнадцатеричном кодировании.

1 стартмани

04.12.2022    2989    12    keyn5565`    0    

13

Обфускатор байт-кода

Защита ПО и шифрование Платформа 1С v8.3 Конфигурации 1cv8 Россия Абонемент ($m)

Обработка, позволяющая запутывать и шифровать байт-код, поставлять модули без исходных текстов и т.д. Протестировано на платформе 8.3.23.1739.

10 стартмани

16.06.2022    10313    80    ZhokhovM    12    

40

Как уберечь конструкторскую документацию от воровства конкурентами?

Защита ПО и шифрование Платформа 1С v7.7 Платформа 1С v8.3 Абонемент ($m)

Как уберечь конструкторскую документацию от воровства конкурентами? Недавно столкнулся с этой проблемой. Заказчик серьёзно обеспокоен утечкой информации о конструкторских разработках в адрес конкурентов, за счет подкупа исполнителей, занимающихся производством по конструкторской документации, операторов технологического оборудования и обрабатывающих центров по изготовлению деталей и сборочных единиц.

2 стартмани

09.03.2022    5656    3    ge_ni    9    

2

Защита конфигураций, обработок, расширений 1С онлайн, управление версиями

Защита ПО и шифрование Платформа 1С v8.3 Конфигурации 1cv8 Абонемент ($m)

Система построена на веб платформе, все управление происходит на сайте в личном кабинете пользователя.

1 стартмани

27.12.2021    4556    2    idm80    11    

9

Пример работы с криптографией в Web-клиенте 1С

Защита ПО и шифрование Платформа 1С v8.3 Конфигурации 1cv8 Абонемент ($m)

Столкнулся с проблемой отсутствия примеров кода по работе в Web-клиенте 1С с криптографией. Свою задачу решил, выкладываю сюда, может, кому пригодится.

1 стартмани

20.12.2021    5487    14    Derushev    1    

5
Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. SerVer1C 749 31.08.22 22:48 Сейчас в теме
В 1С алгоритм шифрования AES можно использовать только через zip файл, что показалось неудобным и не совсем правильным с точки зрения безопасности.

ЖурналЛогов.ДобавитьСтроку("Приватный ключ: "+ПубличныйИПриватныйКлюч);

Н-да... Противоречие самому себе.
2. vit59 57 05.09.22 07:29 Сейчас в теме
(1) Такое впечатление, что вы ищете повод придраться, а не взять что то полезное ))
Читайте "Демонстрация возможностей шифрования ...", понятно же что логирование только для демонстрации, а также использовать для отладки...
Спасибо за отзыв и
Успехов вам !
adm1nb3k; +1 Ответить
Оставьте свое сообщение