Профессиональное задание - Среднее профессиональное

advertisement
Региональный этап Всероссийской олимпиады профессионального
мастерства обучающихся по специальности среднего
профессионального образования
10.02.03 Информационная безопасность автоматизированных систем
Профессиональное задание
1 часть
Используя стандартные элементы управления Windows Form, cоздать
текстовый редактор c возможностью шифрования и дешифрования
введенной текстовой информации. Для шифрования и дешифрования
использовать интерфейс CryptoAPI. При разработке программы использовать
ассиметричный метод шифрования.
Данный текстовый редактор должен обеспечить:
1. Создание открытого и закрытого ключей в виде отдельных файлов с
разным расширением.
2. Шифрование информации с использованием закрытого ключа и класса
RSACryptoServiceProvider среды NET. FrameWork 4.0.
3. Дешифрование информации с использованием открытого ключа и
класса RSACryptoServiceProvider среды NET. FrameWork 4.0.
4. Сохранение зашифрованной информации в отдельном файле.
2 часть
Используя Windows Form для ввода логина и пароля, создать программу
формирования и сохранения зашифрованной информации о пароле
пользователя в отдельном файле. Данная программа должна обеспечить
проверку соответствия пароля и зашифрованной в файле информации.
Для решения поставленной задачи рекомендуется использовать классы
SHA256Managed и HashAlgorithm для получения хештаблицы пароля.
Данные классы описаны в пространстве имен System.Security.Cryptography.
Кроме того, программа должна исключить возможность появления одной и
той же хеш-таблицы пароля даже при наборе разными пользователями
одинакового символьного пароля.
1. Алгоритм выполнения заданий. Работа с CryptoAPI.
Прототипы функций CryptoAPI описаны в файле wincrypt.h. Названия
функций имеют префикс Crypt. Для использования этих функций в свойствах
проекта нужно определить константу _WIN32_WINNT и задать ей значение
0x0400 (или больше). Данная константа применяется в файле wincrypt.h для
проверки версии Windows.
Для некоторых функций CryptAPI также требуются библиотеки crypt32.lib и
advapi32.lib.
2. Криптопровайдер.
Прежде чем использовать какие-либо функции Crypto API, необходимо
запустить криптопровайдер. Делается это с помощью функции CryptAcquireContext:
BOOL CRYPTFUNC CryptAcquireContext(
HCRYPTPROV*
hCryptProvider,//дескриптор
провайдера, out-параметр
LPCTSTR pszContainer,
// имя
контейнера ключей
LPCTSTR pszProvider,
// имя
провайдера
DWORD
dwProvType,
// тип
провайдера
DWORD
dwFlags
// флаги
)
Кроме инициализации криптопровайдера, данную функцию можно
использовать для создания и удаления контейнеров ключей. Для этого
параметру dwFlags присваивается значение, соответственно, CRYPT_NEWKEYSET и CRYPT_DELETEKEYSET.
Функция CryptAcquireContext работает в два этапа: сначала она ищет
криптопровайдер по имени и типу, указанному в аргументах, а затем
контейнер ключей с заданным именем.
По окончании работы с криптопровайдером необходимо вызвать функцию
CryptReleaseContext (см. листинг 1).
Работа с ключами
3. Генерация ключей.
В CryptoAPI имеются функции для генерации ключей любого типа. Функция
CryptGenKey генерирует сессионные ключи и пары для обмена и подписи на
основе случайного числа.
BOOL CRYPTFUNC
HCRYPTPROV
ALG_IG
DWORD
HCRYPTKEY*
)
CryptGenKey(
hProv
Algid
dwFlags
phKey
Сессионные ключи можно сгенерировать также на основе некоторого
заданного значения (пароля) при помощи функции CryptDeriveKey. Это стоит
делать, например, в том случае, когда нужно избежать пересылки
сессионного ключа вместе с зашифрованными данными (см. рис. 2).
Получатель данных, зная пароль и алгоритм, может сам сгенерировать
сессионный ключ и с его помощью расшифровать данные (см. листинг 2).
Рис. 2. Шифрование.
4. Получение дескриптора ключа.
Дескриптор открытого ключа можно получить, вызвав функцию CryptGetUserKey.
5. Экспорт ключей.
Операция экспорта выполняется при сохранении сессионных ключей и при
передаче ключей третьим лицам.
Двоичные данные ключа могут быть получены при помощи функции
CryptExportKey:
BOOL CRYPTFUNC CryptExportKey (
HCRYPTKEY
hKeyToExport
HCRYPTKEY
hCryptKey
DWORD
dwBlobType
DWORD
dwFlags
BYTE*
pbData, // указатель на буфер
DWORD* pdwDataLen ) // длина буфера
Поясним значения аргументов. Первый аргумент — дескриптор
экспортируемого ключа. Второй аргумент — дескриптор ключа, которым
шифруется экспортируемый ключ.
Открытые ключи экспортируются в незашифрованном виде. В этом случае
hCryptKey = 0.
При экспорте сессионных и закрытых ключей необходимо их
предварительно зашифровать. Аргумент hCryptKey должен содержать
дескриптор открытого ключа получателя.
При вызове с аргументом pbData = NULL функция вернет необходимую
длину буфера по адресу, на который указывает аргумент pdwDataLen (см.
листинг 3).
После успешного завершения переменная dwSessionKeyLen будет содержать
действительную длину BLOB-структуры ключа. Это значение необходимо
сохранить для обратной операции — импорта ключа в криптопровайдер.
6 Импорт ключей.
Ключи импортируются функцией CryptImportKey:
CryptImportKey (
HCRYPTPROV hProv
BYTE*
pbData
DWORD
dwDataLen
HCRYPTKEY
DWORD
HCRYPTKEY*
hCryptKey
dwFlags
phImportedKey
)
hCryptKey = 0 в том случае, если импортируемый ключ был зашифрован
асимметричным ключом или не был зашифрован вообще.
Если импортируемый ключ шифровали сессионным ключом, то hCryptKey
должен содержать дескриптор этого ключа.
По окончании работы с ключом необходимо для его дескриптора вызвать
функцию CryptDestroyKey(HCRYPTKEY hKey).
Шифрование и дешифровка данных.
7. В CryptoAPI для шифрования и дешифровки используются и
симметричный, и асимметричный алгоритмы.
Симметричный алгоритм менее надежен, но работает намного быстрее, чем
асимметричный. Поэтому в CryptoAPI применяется комбинация алгоритмов.
Данные шифруются с помощью симметричного алгоритма с сессионным
ключом, а сам сессионный ключ шифруется по асимметричному алгоритму
открытым ключом получателя. Дешифровка происходит в обратном порядке:
сначала закрытым ключом получателя дешифруется сессионный ключ, затем
этим сессионным ключом дешифруются сами данные (см. рисунки 2 и 3).
Рис. 3. Дешифровка.
Таким образом, расшифровать данные можно только, имея закрытый ключ из
той же ключевой пары, что и открытый ключ, которым данные были
зашифрованы.
Для шифрования и дешифровки применяется функция (см. листинг 4).
BOOL CRYPTFUNC CryptEncrypt (
HCRYPTKEY
hKey, // дескриптор ключа
для шифрования
HCRYPTHASH
hHash
BOOL
bFinal
BYTE*
pbData, // параметр [in, out
DWORD* pdwDataLen, // параметр [in, out
DWORD
dwBufferLen )
Последний и предпоследний параметры являются одновременно входными и
выходными. Это означает, что зашифрованные данные записываются поверх
исходных в буфер pbData, а длина данных, соответственно, в dwBufferLen.
Как и в случае с функцией Crypt-ExportKey, CryptEncrypt позволяет
предварительно
определить
необходимый
размер
буфера
под
зашифрованные данные. Для этого нужно вызвать функцию с аргументами:
pbData
= NULL;
pdwDataLen = длина исходных данных.
Длину буфера функция вернет по адресу: pdwDataLen.
Дешифровка данных производится аналогично функцией CryptDecrypt.
Необходимое обрудование:
ПК с ОС Windows и установленной средой NET. FrameWork 4.0.
Download