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

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

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

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

Обновление:

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

Ответы [ 2 ]

5 голосов
/ 06 декабря 2008

Введение

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

Предпосылки

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

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

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

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

Расход ключа в .NET

Используя TripleDESCryptoServiceProvider , я заметил, что в документах указано, что:

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

Так что, если CryptoAPI имеет длину ключа 168, как я получу это в .NET, который поддерживает только кратные 64? Таким образом, сторона API .NET учитывает паритет, а CryptoAPI - нет. Как можно себе представить ... смутился, я .

Итак, со всем этим я пытаюсь выяснить, как восстановить ключ на стороне .NET с правильной информацией о четности. Выполнимо, но не очень весело ... давайте просто оставим это на этом. Как только я получил все это на месте, все закончилось неудачей с капиталом F .

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

Лампочки и фейерверки

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

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

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

CALG_DES 64 бита

CALG_3DES_112 128 бит

CALG_3DES 192 бита

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

.NET Импорт кода твик

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

Array.Reverse( keyByteArray );

Заключение

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

Happy Crypto!

1 голос
/ 08 сентября 2008

Хорошо, забудьте про последний ответ, который я не могу прочитать :) Вы работаете с ключами 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) Я думаю, чтобы преобразовать Endian. Я помню, что это было неочевидно при первом решении проблемы.

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

...