by
30. May 2009 08:58
Статья описывает, как используя богатые возможности .Net Framework реализовать алгоритмы
в 1С:Предприятие. Примеры показаны с применением компонента Elisy .Net Bridge v.2.1,
который распространяется для разработчиков бесплатно.
Криптография используется для защиты информации от просмотра и/или модификации.
Есть два общепринятых алгоритма шифрования: симметричный и асимметричный. Симметричные
алгоритмы более быстрые, но используют для шифрования и расшифровки один и тот же
ключ. Одна сторона вынуждена передавать другой стороне свой ключ, который может
перехватить злоумышленник и расшифровать сообщение.
Асимметричное шифрование использует пару ключей: открытый и закрытый. Сообщение
шифруется открытым ключом, также открытым ключом может быть проверена электронная
подпись. Открытый ключ может быть известен всем. Для генерации цифровой подписи
и расшифровки используется секретный ключ.
Симметричный алгоритм
В состав .Net framework поддерживает следующие алгоритмы симметричного шифрования:
- DES
- RC2
- Rijndael
- TripleDES
- Aes
Для шифрования этими алгоритмами нужен ключ и вектор инициализации. Далее приведен
пример использования класса RC2CryptoServiceProvider.
Перем расшифрованоМассив;
//Код для инициализации компонента Elisy .Net Bridge
ПодключитьВнешнююКомпоненту("AddIn.ElisyNetBridge");
ВК = Новый("AddIn.ElisyNetBridge");
ВК.Активировать("76F93484A6ACDAF144",
"00:1A:4D:5C:3E:BC",
"DyAmVOPyNFTaddNK0jA9muTk2fz2V5+wrnZvZhF8Ws/pE52Loqt9u5QMNhrlVuoQJdENKCRgs8+RmWTI4oVYwUdc8b+kyeuRUNWFaxXuoIPSSDWZAi675CgVpIl5uLbcyB7QKD+9cF6CXcBfD8QD9KqzOF
/LC+O1oFmB3Roo8Pk=");
net = ВК.Новый("Elisy.NetBridge", "Elisy.ElisyNetBridge");
//Создание объекта, ослуживающего RC2-алгоритм
rc2 = net.New("System.Security.Cryptography.RC2CryptoServiceProvider");
//Получаем ключ и вектор инициализации. Генерируются один раз и могут быть использованы многократно.
rc2.GenerateKey();
ключ = rc2.Key;
//Перевод byte[] в сторку base64 для вывода в 1С. Для обратного преобразования может быть использован вызов FromBase64String
Сообщить("Ключ: " + net.CallStatic("System.Convert", "ToBase64String", ключ));
rc2.GenerateIV();
вектор = rc2.IV;
//Перевод byte[] в сторку base64 для вывода в 1С. Для обратного преобразования может быть использован вызов FromBase64String
Сообщить("Вектор: " + net.CallStatic("System.Convert", "ToBase64String", вектор));
////////////////
// Шифрование //
////////////////
шифратор = rc2.CreateEncryptor(ключ, вектор);
потокПамяти = net.New("System.IO.MemoryStream");
криптоПоток = net.New("System.Security.Cryptography.CryptoStream", потокПамяти, шифратор, net.New("System.Security.Cryptography.CryptoStreamMode").Write);
//Преобразовать данные для шифрования в массив byte
исходнаяСтрока = "Какие-то данные для шифрования.";
Сообщить("Строка для шифрования: " + исходнаяСтрока);
дляШифрования = net.GetStatic("System.Text.Encoding", "UTF8").GetBytes(исходнаяСтрока);
//Записать данные в крипто-поток и закрепление.
криптоПоток.Write(дляШифрования, 0, дляШифрования.Length);
криптоПоток.FlushFinalBlock();
//Получить зашифрованный массив байт.
зашифрованоМассив = потокПамяти.ToArray();
зашифрованоСтрока = net.CallStatic("System.Convert", "ToBase64String", зашифрованоМассив);
Сообщить("Зашифрованные данные: " + зашифрованоСтрока);
/////////////////
// Расшифровка //
/////////////////
дешифратор = rc2.CreateDecryptor(ключ, вектор);
потокПамяти = net.New("System.IO.MemoryStream", зашифрованоМассив);
криптоПоток = net.New("System.Security.Cryptography.CryptoStream", потокПамяти, дешифратор, net.New("System.Security.Cryptography.CryptoStreamMode").Read);
//Чтение в массив байт и перевод в кодировку UTF8
считывательПотока = net.New("System.IO.StreamReader", криптоПоток);
расшифрованоСтрока = считывательПотока.ReadToEnd();
Сообщить("Расшифрованная строка: " + расшифрованоСтрока);
Асимметричный алгоритм
.Net framework реализует следующие алгоритмы асимметричного шифрования:
- DSA
- RSA
- ECDSA
- ECDiffieHellman
Для хранения ключей используется отдельный класс параметров. При создании объекта
ключи создаются автоматически. Ключи можно экспортировать в отдельный объект параметров
или строку XML. Ниже представлен пример шифрования/дешифровки через класс RSACryptoServiceProvider.
Сначала шифруется строка, затем она расшифровывается. В конце приведен пример получения
цифровой подписи и проверка ее на валидность.
//Код для инициализации компонента Elisy .Net Bridge
ПодключитьВнешнююКомпоненту("AddIn.ElisyNetBridge");
ВК = Новый("AddIn.ElisyNetBridge");
ВК.Активировать("76F93484A6ACDAF144",
"00:1A:4D:5C:3E:BC",
"DyAmVOPyNFTaddNK0jA9muTk2fz2V5+wrnZvZhF8Ws/pE52Loqt9u5QMNhrlVuoQJdENKCRgs8+RmWTI4oVYwUdc8b+kyeuRUNWFaxXuoIPSSDWZAi675CgVpIl5uLbcyB7QKD+9cF6CXcBfD8QD9KqzOF/LC+O1oFmB3Roo8Pk=");
net = ВК.Новый("Elisy.NetBridge", "Elisy.ElisyNetBridge");
//Создание объекта, ослуживающего RSA-алгоритм
rsa = net.New("System.Security.Cryptography.RSACryptoServiceProvider");
//Получаем ключи. Генерируются автоматически при создании объекта RSACryptoServiceProvider и могут быть использованы многократно.
открытыйКлюч = rsa.ToXmlString(Ложь);
Сообщить("Открытый ключ: " + открытыйКлюч);
секретныйКлюч = rsa.ToXmlString(Истина);
Сообщить("Секретный ключ: " + секретныйКлюч);
//Преобразовать данные для шифрования в массив byte
исходнаяСтрока = "Какие-то данные для шифрования.";
Сообщить("Строка для шифрования: " + исходнаяСтрока);
данныеДляШифрования = net.GetStatic("System.Text.Encoding", "UTF8").GetBytes(исходнаяСтрока);
////////////////
// Шифрование //
////////////////
//Применить открытый ключ
rsa.FromXmlString(открытыйКлюч);
//Получить зашифрованный массив байт.
зашифрованоМассив = rsa.Encrypt(данныеДляШифрования, false);
зашифрованоСтрока = net.CallStatic("System.Convert", "ToBase64String", зашифрованоМассив);
Сообщить("Зашифрованные данные: " + зашифрованоСтрока);
/////////////////
// Расшифровка //
/////////////////
//Применить секретный ключ
rsa.FromXmlString(секретныйКлюч);
//Расшифровать
расшифрованныеДанные = rsa.Decrypt(зашифрованоМассив, false);
расшифрованнаяСтрока = net.GetStatic("System.Text.Encoding", "UTF8").GetString(расшифрованныеДанные);
Сообщить("Расшифрованная строка: " + расшифрованнаяСтрока);
/////////////////////////////////
// Вычисление цифровой подписи //
/////////////////////////////////
//Применить секретный ключ
rsa.FromXmlString(секретныйКлюч);
//Вычислить подпись
цифроваяПодпись = rsa.SignData(данныеДляШифрования, net.New("System.Security.Cryptography.SHA1CryptoServiceProvider"));
цифроваяПодписьСтрока = net.CallStatic("System.Convert", "ToBase64String", цифроваяПодпись);
Сообщить("Цифровая подпись: " + цифроваяПодписьСтрока);
///////////////////////////////
// Проверка цифровой подписи //
///////////////////////////////
//Применить секретный ключ
rsa.FromXmlString(открытыйКлюч);
//Проверить цифровую подпись
Если rsa.VerifyData(данныеДляШифрования, net.New("System.Security.Cryptography.SHA1CryptoServiceProvider"), цифроваяПодпись) Тогда
Сообщить("Цифровая подпись валидная");
Иначе
Сообщить("Цифровая подпись невалидная");
КонецЕсли
56579dcd-50f2-431b-9977-eeab3ac1d2cc|2|5.0
Tags: 1C.Net
1C.Net