| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Общие вопросы > CryptoAPI RSA шифрование |
| Автор: tofreesky 8.2.2012, 23:06 | ||
Весь листинг из примеров из rsdn. Вопрос -- почему входной файл расшифровывается тем же публичным ключом, ведь должен приватным.
|
| Автор: tofreesky 8.2.2012, 23:39 |
| Это так выходит, когда все выполняется единоразово, а если запустить программу два раза, с отдельными действиями для шифрования и расшифровывание, то публичный ключ для расшифровывания не подойдет. Теперь экспортировал приватный ключ, но и им раскриптовать данные не удается. Ошибка импорта 0x80090003 (NTE_BAD_KEY) |
| Автор: volatile 9.2.2012, 00:03 |
| tofreesky, очень перегруженная функция. Скорей всего запутались где-то в скобках. Такой код понять трудно даже вам самому, почему вы думаете что другим будет легче? Вот наприме строки у вас очень не плохо получилось зашифровать tofreesky, поробуйте разбить функцию на несколько штук, вменяемого размера. Возможно после этого, и помощь уже не понадобится |
| Автор: tofreesky 9.2.2012, 00:05 |
| Я же сказал что это с rsdn, тут код не большой и понятный. Так по делу есть какие-то мысли? На 104 строке где расшифровка, ведь передаваемый приватный ключ был зашифрован сессионным, который нигде не сохранен, из-за этого и ошибка? |
| Автор: tofreesky 9.2.2012, 10:42 | ||
Все равно ничего нового, вот немного измененный код:
GenerateKey(); генерирует приватный и публичный ключи ProcessFile(); шифрует или расшифровывает в зависимости от четвертого параметра. Так вот, теперь не выходит расшифровать файл приватным ключом, NTE_BAD_KEY при импорте. В чем дело? Он же шифруется еще и сессионым, а он ни где не сохранятся, значит его нужно сохранить и предварительно расшифровать приватный ключ? Но как? |
| Автор: feodorv 9.2.2012, 17:05 | ||||||||
Ещё раз. По оригинальному коду MS. Файл шифруется и расшифровывается симметричным сессионным ключом. Он создаётся при "encode":
Таким образом, hKey (сессионный ключ) шифруется с помощью hPubKey (открытый пользовательский ключ), и всё это записывается в виде набора байт в kb. А уже потом структура EncFileHeader вместе с зашифрованным сессионным ключом сбрасывается в выходный файл в виде заголовка этого файла, после которого будет записано шифруемое содержимое оригинального файла. Поэтому: в корне не верно:
Добавлено через 5 минут и 27 секунд И для полной картины не хватает
|
| Автор: tofreesky 9.2.2012, 17:22 | ||
| Все равно не понятно почему приватным ключом не удается расшифровать файл? tools.h
|
| Автор: tofreesky 9.2.2012, 17:41 | ||
| В общем надо забить на эту все кривую реализацию RSA у MS, на другой системе уже падает на: Самом начале функции
С ошибкой NTE_BAD_KEYSET. Есть ли нормальные либы для RSA, только не по 25 мб, которые. |
| Автор: feodorv 9.2.2012, 19:07 | ||||||||
Прилизал немного код и перевёл в Си:
Файл нормально зашифровывается и расшифровывается, только подпись не проходит проверку, пока не разобрался, почему. Добавлено через 13 минут и 53 секунды Разобрался. Для подписи использовался приватный AT_SIGNATURE ключ, а для проверки подписи - публичный AT_KEYEXCHANGE ключ. Нестыковочка Достаточно в коде
поменять AT_SIGNATURE на AT_KEYEXCHANGE и... все работает!!! Всё, даже вариант без
|
| Автор: feodorv 9.2.2012, 19:23 |
Что-то я сомневаюсь, что понятный Ха, может, криво где-то в другом месте??? |
| Автор: tofreesky 9.2.2012, 20:06 |
| Только я не пойму что нового в вашем коде, по прежнему те же изначальные проблемы, приватный ключ не расшифровывает сообщение, да и генирирование приватного ключа в вашем коде нет. |
| Автор: feodorv 9.2.2012, 20:24 |
Так это тот же майксрософтовский код, только сизированный А вот новое это то, что он работает. Не понял, о чём Вы. Ох... Может Вы имеете в виду, что , но никакого отношения к расшифровке файла, да ещё и приватным(!) ключом это не имеет. |
| Автор: tofreesky 9.2.2012, 20:26 | ||
| Так в чем смысл, это получается симметричное шифрование, а не асимметричность, раз можно зашифровать и расшифровать одним ключом. Добавлено через 10 минут и 13 секунд
|
| Автор: feodorv 9.2.2012, 20:45 | ||
Сам файл шифруется симметричным сессионным ключом, который должен быть ещё передан вместе с зашифрованным файлом, чтобы его ещё можно было расшифровать. А вот уже сессионный ключ шифруется открытым (несимметричным) пользовательским ключом и дешифруется закрытым пользовательским. Такая схема совершенно обычна в современной криптографии. Если Вы начнёте закрытым ключом шифровать всё подряд (чтобы послать данные владельцу открытого), то опытный криптолог в конце концов сможет вычислить Ваш закрытый ключ, имея на руках множество данных. В то же время, сессионный ключ короткий (256 байт), почти случайный, существует короткое время - на сессию (то есть не повторяется), фиг выявишь какие-то закономерности в паре закрытый/открытый ключ |
| Автор: tofreesky 9.2.2012, 20:46 |
| Вы вопроса не видите что ли? Все что вы говорите понятно, но так где в вашем коде приватный ключ? Одним и тем же расшифровывается. |
| Автор: feodorv 9.2.2012, 21:13 |
Гм. По-моему, так это Вы ответа не видите. А ещё говорите понятный код(((( Код не мой. А приватный ключ получаем через вызов CryptGetUserKey. Добавлено через 42 секунды Им расшифровывается сессионный ключ. Добавлено через 5 минут и 3 секунды То, что Вы нагородили с "key_pub.rsa" и "key_prv.rsa" - совершенно неверно, так как в случае дешифровки публичный ключ нужен только для проверки подписи. |
| Автор: tofreesky 9.2.2012, 21:54 |
| Там мне нужно одним ключом(публичным) шифровать, а приватным расшифровывать. Обычная схема. Только в вашем(моем) коде используется один ключ для всего. А мне нужно два отдельных. |
| Автор: feodorv 9.2.2012, 22:12 | ||
Да нет же. Используются и открытый, и приватный ключи.
Так не делают. |
| Автор: tofreesky 9.2.2012, 22:23 | ||||
Где же? Видно что экспортируется публичный ключ.
Лол. А как делают? Извините, но, вы вообще о асимметричной криптографии не слышали походу.... Добавлено через 2 минуты и 15 секунд Ассиметричное шифрование (криптография с открытым ключом) - асимметричная схема, в которой применяются пары ключей: открытый ключ (public key), который зашифровывает данные, и соответствующий ему закрытый ключ (private key), который их расшифровывает. Открытый ключ можно распространить хоть по всему миру, в то время как закрытый держится в тайне. Любой человек с копией открытого ключа может зашифровать информацию, которую сможет прочитать только владелец закрытого ключа. Кто угодно. Даже люди, с которыми вы прежде никогда не встречались. |
| Автор: feodorv 9.2.2012, 22:57 | ||||||
Так можно, но так не делают:
http://www.rsdn.ru/article/crypto/usingcryptoapi.xml
Поражён Вашими знаниями Мдя. Экспортируется публичный ключ "для обмена". Это значит, что Вы можете файл с незашифрованным публичным ключом перенести на другую инсталляцияю ОС и с помощью него зашифровывать данные, которые может расшифровать только владелец приватного ключа. Но не "им зашифровывать", а "с помощью него зашифровывать", так как схема более изощрённая. Экспорт приватного ключа для расшифровки данных не имеет смысла. Схема зашифровки файла:
Схема расшифровки файла:
|
| Автор: tofreesky 9.2.2012, 23:09 | ||
Откуда его берут? |
| Автор: feodorv 10.2.2012, 00:08 | ||
Как откуда??? Из локального контейнера ключей! Как Вы думаете, что кроме всего делает функция CryptAcquireContext?
Если контейнера ключей с именем, совпадающим с именем текущего пользователя (второй аргумент функции - NULL), не существует, то создадим его (на что указывает флаг CRYPT_NEWKEYSET). Если задать флаг CRYPT_DELETEKEYSET, то можно удалить этот контейнер. Именно в этом контейнере хранятся пары открытый/закрытый ключ (AT_KEYEXCHANGE или AT_SIGNATURE). |
| Автор: feodorv 10.2.2012, 00:53 | ||||||||
| Не поленился воспользоваться советом volatile: Ну и немного изменил код, убив всякое упоминание о "key.rsa". Генерация ключей
Шифрование файла
Дешифрование файла
Заголовочный файл utils.h
Код рабочий, хотя я и мог где-нибудь напортачить))) Как видно, при шифровании и дешифровании файла вызывается одна и та же функция CryptGetUserKey( hProv, AT_KEYEXCHANGE, &hPubKey или &hPrivKey), в реальности возвращающая сразу пару ключей. В зависимости от функции используется либо открытый, либо закрытый ключ. В MS-коде просто подчеркнули использование публичного ключа для шифрования, чтобы не было никаких сомнений, а вот использование приватного ключа не столь очевидно. |
| Автор: xvr 10.2.2012, 09:20 | ||||
Так, сугубо для уточнения - этой программой (и с закрытым ключем) вы сможете расшифровать файл только на той машине, где его шифровали. Если же вам нужно расшифровывать его на другой машине, то туда нужно будет перенести этот самый KEYSET (или сменить способ шифрования и обмена ключами) |
| Автор: tofreesky 10.2.2012, 18:53 |
| Мне не нужно хранить ключи в контейнерах, мне нужно два файла на жестком диске публичный ключ и приватный ключ. Публичным шифровать, а приватным расшифровывать. Так видимо на криптоапи сделать невозможно. |
| Автор: feodorv 10.2.2012, 19:49 | ||
Что именно диктует такую необходимость? |
| Автор: tofreesky 10.2.2012, 19:56 |
| Как мне отдавать пользователям публичный ключ, и носить с собой программу работающую с приватным ключом? |
| Автор: feodorv 10.2.2012, 20:48 | ||
Это возможно, схему распишу немного позже. |
| Автор: feodorv 11.2.2012, 00:21 | ||||
| Бр, устал бороться, экспорт работает, импорт - нет ((( Ошибка NTE_BAD_VER... Хотя вряд ли это с криптопровайдером связано))) Экспорт:
Импорт:
|
| Автор: tofreesky 11.2.2012, 00:26 |
| А экспорт публичного ключа и импорт его и использование, все как в старом коде? |
| Автор: feodorv 11.2.2012, 00:36 | ||||||
Хотя ошибку нашёл (в экспорте):
а нужно:
Что уж там выводилось, одному Богу известно))) Экспорт и импорт работают. Осталось проверить шифрование. Добавлено через 12 минут и 30 секунд
На своём (домашнем) компьютере выполняется "экспорт.exe", получается файл с именем mykey.rsa. На (любом) удалённом компьютере выполняется "импорт.exe" (с прилагающимся файлом mykey.rsa). И на домашнем, тоже, так как имена контейнеров я сделал разными))) Больше ничего в плане генерации ключей делать не нужно. Ключевая пара импортируется в контейнер с именем Movable2 (можно поменять в коде). Далее берутся исходники http://forum.vingrad.ru/index.php?showtopic=346747&view=findpost&p=2458375, заменяется NULL в вызовах CryptAcquireContext на "Movable2", компиляться только encrypt.exe и decrypt.exe, которыми Вы как раз шифруете и дешифруете файлы. Для постороннего человека надо написать свою утилиту экспорта только публичного ключа и шифрования им. В любом случае логику задачи нужно проработать, чтобы не запутаться, кто, что и чем шифрует))) А сама задача вполне решаема средствами CryptoAPI. |
| Автор: feodorv 11.2.2012, 11:17 |
| Итак: задача естественным образом разделяется на 2 части - "для себя" и "для других". Для себя:
Для других:
Все названия условны. Примеры кода, реализующие каждую из этих программ, у Вас есть. При модификации примерного кода в рабочий нужно учесть 3-а момента:
Как-то так))) |
| Автор: darklight131080 3.7.2012, 12:56 |
| Здравствуйте!!! Я только начинаю разбираться. Если тупо сменить во всём коде 1024 на 2048 то получим 2048 bit - ключ? При компиляции вылезли такие варнинги: 1>RSADEMO.CPP(77): warning C4293: <<: отрицательное или слишком большое смещение; поведение не определено unsigned __int64 fSize = (dwSzHigh << 32) + dwSzLow; 2>RSADEMO.CPP(142): warning C4293: <<: отрицательное или слишком большое смещение; поведение не определено fEncSize = (dwSzHigh << 32) + dwSzLow - sizeof(EncFileHeader) - 1024/8; //размер зашифрованных данных Спасибо за внимание!!! P.S. Прошу не пинать сильно, а по возможности подсказать как из данных сорцев сделать 2048 и критичны ли варнинги\как их устарнить? |
| Автор: xvr 3.7.2012, 16:01 | ||
Вынужден вас огорчить - тут шифрование выполняется даже не с 1024 битным ключом, а гораздо более коротким |
| Автор: darklight131080 3.7.2012, 16:09 |
| Кто может помочь модифицировать до 2048 bit? Цена вопроса? |
| Автор: feodorv 9.7.2012, 23:42 | ||||
Какой именно ключ Вы хотите сделать 2048-битным: симметричный или несимметричный? Критичны. Устраняются так:
|
| Автор: tofreesky 8.8.2012, 13:58 |
| И как все же экспортировать пару ключей? |
| Автор: tofreesky 16.8.2012, 14:21 |
| ??????? |
| Автор: feodorv 16.8.2012, 23:48 |
Все коды даны. Все соображения высказаны. Вам остаётся только немного поэкспериментировать и довести задуманное до конца. |
| Автор: tofreesky 17.8.2012, 17:09 |
| del |