Модераторы: feodorv, GremlinProg, xvr, Fixin
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> cryptoapi CryptExportKey 
:(
    Опции темы
frying
Дата 13.5.2012, 19:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 23
Регистрация: 17.10.2011

Репутация: нет
Всего: нет



Доброго времени суток!
Мне нужно экспортировать ключ в файл. Использую для этого CryptExportKey. Вот код программы:
Код

#define _WIN32_WINNT 0x0400

#include <iostream>
#include <stdlib.h>
#include <fstream>
#include <Windows.h>
#include <WinCrypt.h>
#pragma comment(lib, "advapi32.lib")
#include <WinError.h>
#include <string>

using namespace std;

int errorReturn()
{
    cout << hex << GetLastError() << endl;
    //cin.get();
    return 1;
}

int main(int argc, char* argv[]){
    ofstream passOfs;
    passOfs.open("password");
    HCRYPTPROV hProv = 0;
    // Получение контекста криптопровайдера
    if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) {
        cout << "CryptAcquireContext Error";
        //cin.get();
        exit(1);
    }
    HCRYPTKEY hSessionKey = 0;
    // Генерация сессионного ключа
    if (!CryptGenKey(hProv, CALG_RC2, CRYPT_EXPORTABLE, &hSessionKey)) {
        cout << "CryptGenKey Error";
        //cin.get();
        return 1;
    } else {
        std::cout << "Session key generated" << std::endl;
        std::cout << hSessionKey << std::endl;
    }

    HCRYPTKEY hPublicKey = NULL;
    HCRYPTHASH hPassHash = NULL;
    //Функция создающая хеш-объект, предназначенный для генерации хеш-значения данных.
    if (CryptCreateHash(hProv, CALG_MD5, NULL, 0, &hPassHash)) {
        cout << "Hash for public key generated" << endl;
        cout << hPassHash << endl;
    } else {
        cout << "Hash creation fail";
        exit(1);
    }
    //Основная функция хеширования данных.
    char password[] = "12345";
    if (!CryptHashData(hPassHash, (BYTE*) password, strlen(password), 0)) {
        cout<< "Error CryptHashData";
    } else {
        cout << "CryptHashData generated" << endl;
    }
    // Генерация сессионного ключа
    if (!CryptDeriveKey(hProv, CALG_3DES, hPassHash, CRYPT_EXPORTABLE, &hPublicKey)) {
        cout << "CryptDerKey Error";
        return 1;
    } else {
        std::cout << "Derive session key generated" << std::endl;
        std::cout << hPublicKey << std::endl;
    }

    DWORD count = 0;
    if (!CryptExportKey(hSessionKey, hPublicKey, SIMPLEBLOB, 0, NULL, &count)) {
        cout << "Error Initial of CryptExportKey: ";
        errorReturn();
        return 1;
    }
    cout << "count " << count << endl;

    BYTE* pdDataKey = new BYTE[count];
    if (!CryptExportKey(hSessionKey, hPublicKey, SIMPLEBLOB, 0, pdDataKey, &count)) {
        cout << "Error CryptExportKey: ";
        errorReturn();
        return 1;
    }
    cout << "data " << pdDataKey << endl;

    passOfs.write((char*) pdDataKey, count);
    passOfs.close();
}


На функции CryptExportKey программа выдаёт ошибку 80090003 (NTE_BAD_KEY), что, мол, непорядок с ключами. Почему, в чем ошибка? 
PM MAIL   Вверх
feodorv
Дата 14.5.2012, 01:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 9
Всего: 45



http://www.microsoft-questions.com/microso...m-password.aspx
Цитата

SIMPLEBLOB always encrypts with a PUBLIC key. ie. if you specify SIMPLEBLOB
in CryptExportKey, then the hExpKey parameter must be a public key. In your
code you generate a (derived) secret key. Since that key is not public key,
you get the NTE_BAD_KEY error.
You would need to use SYMMETRICWRAPKEYBLOB if you want to wrap your session
key with your derived key. (Another option is to export your session key in
plaintext format with PLAINTEXTKEYBLOB, then simply encrypt the key value
with your derived wrapper key.)


Это сообщение отредактировал(а) feodorv - 14.5.2012, 01:06


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
frying
Дата 14.5.2012, 14:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 23
Регистрация: 17.10.2011

Репутация: нет
Всего: нет



feodorv,  спасибо, при SYMMETRICWRAPKEYBLOB  запись в файл прошла успешно, теперь пробую считать значение в файле используя CryptImportKey.  Просто добавил к коду выше ещё:
Код

ifstream passIfs;
passIfs.open("password");

DWORD dwDataLen = 0;
//Вычисляем длину входного файла.
passIfs.seekg(0, ios_base::end);
int bufLen = passIfs.tellg();
passIfs.seekg(0, ios_base::beg);
//Готовим буфер для чтения.
BYTE *bufAll = new BYTE[bufLen];
passIfs.read((char*) bufAll, bufLen);
cout << "bufLen " << bufLen << endl;
HCRYPTKEY readKey = 0;
if (!CryptImportKey(hProv, bufAll, bufLen, hPublicKey, 0, &readKey)) {
    cout << "Error CryptImportKey: ";
    errorReturn();
} else {
    cout << "readKey " << readKey << endl; 
}


Но ключ выводится не тот, или вообще выдается ошибка NTE_BAD_DATA.
PM MAIL   Вверх
feodorv
Дата 14.5.2012, 15:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 9
Всего: 45



Цитата(frying @  14.5.2012,  15:46 Найти цитируемый пост)
Но ключ выводится не тот, или вообще выдается ошибка NTE_BAD_DATA. 

Цитата(frying @  14.5.2012,  15:46 Найти цитируемый пост)
if (!CryptImportKey(hProv, bufAll, bufLen, hPublicKey, 0, &readKey))

Создайте hPublicKey по-новой  smile А то Вы применяете уже юзаный ключ, состояние которого отлично от первоначального...


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
frying
Дата 14.5.2012, 17:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 23
Регистрация: 17.10.2011

Репутация: нет
Всего: нет



Пробую сделать новый ключ: опять не подходит, что интересно, но даже CryptDeriveKey не совпадают. Добавил этот код в конце файла:
Код

//Теперь проверяем полученные значения.
    HCRYPTPROV hImportProv = 0;
    // Получение контекста криптопровайдера
    if (!CryptAcquireContext(&hImportProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) {
        cout << "CryptAcquireContext Error";
        exit(1);
    }
    HCRYPTKEY hPublicImportKey = NULL;
    HCRYPTHASH hPassImportHash = NULL;
    //Функция создающая хеш-объект, предназначенный для генерации хеш-значения данных.
    if (CryptCreateHash(hImportProv, CALG_MD5, NULL, 0, &hPassImportHash)) {
        cout << "Hash for import public key generated" << endl;
        //cout << hPassImportHash << endl;
    } else {
        cout << "Hash import creation fail";
        exit(1);
    }
    //Основная функция хеширования данных.
    char passwordNew[] = "12345";
    if (!CryptHashData(hPassImportHash, (BYTE*) passwordNew, strlen(passwordNew), 0)) {
        cout<< "Error CryptHashData for import";
    } else {
        cout << "CryptHashData for import generated" << endl;
    }
    // Генерация сессионного ключа
    if (!CryptDeriveKey(hImportProv, CALG_3DES, hPassImportHash, CRYPT_EXPORTABLE, &hPublicImportKey)) {
        cout << "CryptDerKey for import Error";
        return 1;
    } else {
        std::cout << "Derive session import key generated" << std::endl;
        std::cout << hPublicImportKey << std::endl;
    }

    DWORD dwDataLen = 0;
    //Вычисляем длину входного файла.
    passIfs.seekg(0, ios_base::end);
    int bufLen = passIfs.tellg();
    passIfs.seekg(0, ios_base::beg);
    //Готовим буфер для чтения.
    BYTE *bufAll = new BYTE[bufLen];
    passIfs.read((char*) bufAll, bufLen);
    cout << "bufLen " << bufLen << endl;
    HCRYPTKEY readKey = 0;
    if (!CryptImportKey(hImportProv, bufAll, bufLen, hPublicImportKey, 0, &readKey)) {
        cout << "Error CryptImportKey: ";
        errorReturn();
    } else {
        cout << "readKey " << readKey << endl; 
    }

PM MAIL   Вверх
feodorv
Дата 14.5.2012, 17:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 9
Всего: 45



Цитата(frying @  14.5.2012,  18:11 Найти цитируемый пост)
даже CryptDeriveKey не совпадают

Попробуйте флаг CRYPT_NO_SALT при CryptGenKey smile 
Цитата

The Base Provider creates 40-bit symmetric keys created with eleven bytes of zero-value salt, eleven bytes of nonzero salt if CRYPT_CREATE_SALT is specified, or no salt value. A 40-bit symmetric key with zero-value salt, however, is not equivalent to a 40-bit symmetric key without salt. For interoperability, keys must be created without salt. This problem results from a default condition that occurs only with keys of exactly 40 bits. All other key lengths do not have salt allocated by default.


Это сообщение отредактировал(а) feodorv - 14.5.2012, 17:21


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Системное программирование и WinAPI"
Fixin
GremlinProg
xvr
feodorv
  • Большое количество информации и примеров с использованием функций WinAPI можно найти в MSDN
  • Описание сообщений, уведомлений и примеров с использованием компонент WinAPI (BUTTON, EDIT, STATIC, и т.п.), можно найти в MSDN Control Library
  • Непосредственно, перед созданием новой темы, проверьте заголовок и удостоверьтесь, что он отражает суть обсуждения.
  • После заполнения поля "Название темы", обратите внимание на наличие и содержание панели "А здесь смотрели?", возможно Ваш вопрос уже был решен.
  • Приводите часть кода, в которой предположительно находится проблема или ошибка.
  • Если указываете код, пользуйтесь тегами [code][/code], или их кнопочными аналогами.
  • Если вопрос решен, воспользуйтесь соответствующей ссылкой, расположенной напротив названия темы.
  • Один топик - один вопрос!
  • Перед тем как создать тему - прочтите это .

На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы .


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема »


 




[ Время генерации скрипта: 0.0794 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.