Как я могу использовать большой двоичный объект ключа, сгенерированный из Win32 CryptoAPI, в моем приложении .NET?

StackOverflow https://stackoverflow.com/questions/49211

Вопрос

У меня есть существующее приложение, написанное на C ++ для Windows.Это приложение использует Win32 CryptoAPI для генерации сеансового ключа TripleDES для шифрования / дешифрования данных.Мы используем показатель одного трюка экспортировать ключ сеанса в виде большого двоичного объекта, что позволяет хранить большой двоичный объект где-либо в расшифрованном формате.

Вопрос в том, как мы можем использовать это в нашем .СЕТЕВОЕ приложение (C #).Фреймворк инкапсулирует / оборачивает большую часть того, что делает CryptoAPI.Частично проблема заключается в том, что CryptAPI утверждает, что алгоритм TripleDES для Microsoft Усовершенствованный Поставщик криптографических средств равен 168 битам (3 ключа по 56 бит).Однако в .NET Framework указано, что их ключи равны 192 битам (3 ключа по 64 бита).По-видимому, 3 дополнительных байта в .NET framework предназначены для обеспечения четности?

В любом случае, нам нужно прочитать ключевую часть из большого двоичного объекта и каким-то образом иметь возможность использовать это в нашем .СЕТЕВОЕ приложение.В настоящее время мы не получаем ожидаемых результатов при попытке использовать ключ в .NET.Расшифровка с треском проваливается.Мы были бы очень признательны за любую помощь.

Обновить:

Я работал над способами решения этой проблемы и придумал решение, которое я опубликую со временем.Тем не менее, все равно был бы признателен за любые отзывы от других.

Это было полезно?

Решение

Вступление

Наконец-то я добираюсь до публикации решения.Я надеюсь, что это окажет некоторую помощь другим людям, которые, возможно, занимаются подобными вещами.На самом деле не так много упоминаний о том, чтобы делать это в другом месте.

Предварительные условия

Для того чтобы многое из этого имело смысл, необходимо прочитать показатель одного трюка, который позволяет вам экспортировать сеансовый ключ в большой двоичный объект (хорошо известная байтовая структура).Затем можно делать с этим потоком байтов все, что угодно, но он содержит самый важный ключ.

Документация MSDN сбивает с толку

В этом конкретном примере я использую Microsoft Усовершенствованный Поставщик криптографических средств, с Тройным DES (CALG_3DES) алгоритм.Первое, что бросило меня в дрожь, был тот факт, что длина ключа указана в 168 битах при длине блока 64 бита.Как длина ключа может быть 168?Три ключа по 56 бит?Что происходит с другим байтом?

Итак, с этой информацией я начал читать в другом месте, что последний байт на самом деле равен четности, и по какой-то причине CryptoAPI удаляет это.Так ли это на самом деле?Кажется немного сумасшедшим, что они пошли бы на это, но ладно.

Использование ключа в .NET

Используя TripleDESCryptoServiceProvider ( Поставщик услуг Tripledescryptoservice ), Я заметил , что замечания в документах указывают на то , что:

Этот алгоритм поддерживает длину ключа от 128 до 192 бит с шагом в 64 бита.

Итак, если CryptoAPI имеет длину ключа 168, как я могу ввести это в.СЕТЬ, которая поддерживает только поддержку, кратную 64?Следовательно, .Сетевая часть API учитывает четность, в отличие от CryptoAPI.Как можно было себе представить... я был сбит с толку.

Итак, учитывая все это, я пытаюсь выяснить, как восстановить ключ на стороне .NET с надлежащей информацией о четности.Выполнимо, но не очень весело...давайте просто оставим все как есть.Как только я все это поставил на место, все закончилось полным провалом с БОЛЬШОЙ буквы F.

Все еще со мной?Хорошо, потому что я только что снова упал с лошади.

Электрические лампочки и фейерверки

Низко и вот, когда я просматриваю MSDN для получения каждого последнего бита информации, я нахожу конфликтующий фрагмент в Win32 Ключ CryptExportKey функция.Низко и вот я нахожу этот кусочек бесценной информации:

Для любой из перестановок ключей DES, использующих PLAINTEXTKEYBLOB, может быть экспортирован только полный размер ключа, включая бит четности.Поддерживаются следующие размеры клавиш.

Поддерживаемый алгоритмом размер ключа

CALG_DES 64 бита

CALG_3DES_112 128 бит

CALG_3DES 192 бита

Таким образом, он экспортирует ключ, кратный 64 битам!У-у-у!Теперь исправим код на стороне .NET.

Настройка кода импорта .NET

Порядок байтов важно иметь в виду при импорте потока байтов, содержащего ключ, который был экспортирован в виде большого двоичного объекта из CryptoAPI.Следовательно, два API не используют одинаковый порядок байтов, поскольку @nic-сильный указывает, что обращение массива байтов вспять необходимо перед фактической попыткой использования ключа.В остальном все работает так, как ожидалось.Просто решаемая:

Array.Reverse( keyByteArray );

Заключение

Я надеюсь, что это кому-то там поможет.Я потратил слишком много времени, пытаясь отследить это.Оставляйте любые комментарии, если у вас возникнут дополнительные вопросы, и я попытаюсь помочь вам уточнить любые детали.

Счастливой Криптографии!

Другие советы

Хорошо, забудьте последний ответ, который я не могу прочитать :) Вы работаете с ключами 3Des, а не с ключами RSA.

Я работал над кучей кода для обмена ключами между .NET, CryptoAPI и openssl.Здесь я нашел много хороших примеров кода для выполнения ключевых преобразований:

http://www.jensign.com/JavaScience/cryptoutils/index.html

В некоторых из этих примеров есть кое-что из 3des, но это было связано с openssl -> .NET iirc.

Я также только что просмотрел код ключа RSA, и одна вещь, которую я заметил, что я делаю, - это использование Array.Reverse() для всех ключевых частей ключа RSA (D, DP, DQ, InverseQ, Modulus, P, Q), я думаю, для преобразования конечного символа.Я помню, что это было неочевидно, когда я впервые взялся за решение проблемы.

Надеюсь, что-то из этого поможет.Удачи.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top