Как создать и использовать криптографию с открытым ключом в WinCrypt - PullRequest
2 голосов
/ 02 февраля 2011

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

Вот примерный план того, как мой текущий код генерирует пару ключей шифрования, я удалил код проверки ошибок для удобства чтения

// MAKE AN RSA PUBLIC/PRIVATE KEY:
    CryptGenKey(hProv, CALG_RSA_KEYX, CRYPT_EXPORTABLE, &hKey);

// NOW LET'S EXPORT THE PUBLIC KEY:
    DWORD keylen;
    CryptExportKey(hKey,0,PUBLICKEYBLOB,0,NULL,&keylen);
    LPBYTE KeyBlob;
    KeyBlob = (LPBYTE)malloc(keylen);
    CryptExportKey(hKey,NULL,PUBLICKEYBLOB,0,KeyBlob,&keylen);
    ofstream outputkey;
    outputkey.open("TestPublicKey.txt", ios_base::out | ios_base::binary);
    for(size_t i=0; i &lt keylen; ++i)
        outputkey&lt&ltKeyBlob[i];
    outputkey.close();
    free(KeyBlob);

// NOW LET'S EXPORT THE PRIVATE KEY:
    CryptExportKey(hKey, 0, PRIVATEKEYBLOB,0,NULL,&keylen);
    KeyBlob = (LPBYTE)malloc(keylen);
    CryptExportKey(hKey,NULL,PRIVATEKEYBLOB,0,KeyBlob,&keylen)
    outputkey.open("TestPrivateKey.txt", ios_base::out | ios_base::binary);
    for(size_t i=0;i&ltkeylen;++i)
        outputkey&lt&ltKeyBlob[i];
    outputkey.close();
    free(KeyBlob);

// ENCRYPT A (SHORT) TEST MESSAGE [SHOULD JUST BE ANOTHER ALG'S KEY LATER]:
    DWORD encryptBufferLen=0;
    CryptEncrypt(hKey, 0, true, 0, NULL, &encryptBufferLen, 0); // how much space?
    BYTE* encryptionBuffer = (BYTE*)malloc(encryptBufferLen);
    memcpy(encryptionBuffer, TestMessage, TestMessageLen); // move for in-place-encrypt
    CryptEncrypt(hKey,0,true,0, encryptionBuffer, &bufferlen, encryptBufferLen );

    ofstream message;
    message.open("Message.txt", ios_base::out | ios_base::binary);
    for(size_t i=0;i&ltencryptBufferLen;++i)
        message&lt&ltencryptionBuffer[i];
    message.close();

Мои два экспортированных ключа различаются, но оба могут расшифровать сообщение без загрузки другого ключа. Кроме того, если я зашифрую новое сообщение в новом сеансе, который загружает экспортированный открытый ключ, я все равно могу дешифровать его любым ключом.

Может кто-нибудь посоветовать мне, что я могу делать неправильно или пропустить? Я нахожусь на совершенно неверном пути?

Ответы [ 4 ]

0 голосов
/ 10 июля 2015

Используете ли вы CryptImportKey для обоих ключей?Похоже, что ваш шифрование просто использует дескриптор ключа, который вы сгенерировали.Для правильного выполнения пар Public / Private вы должны экспортировать только открытый ключ с помощью CryptExportKey и передавать его всем, кто в этом нуждается.Хотя это не настоящее «шифрование», это способ для человека узнать, что это от вас.

0 голосов
/ 04 мая 2011

Я пока еще не эксперт в области шифрования! но сейчас я работаю с этим, чтобы почувствовать вашу боль ...

Что-то не так с битом шифрования

// ENCRYPT A (SHORT) TEST MESSAGE [SHOULD JUST BE ANOTHER ALG'S KEY LATER]:
DWORD encryptBufferLen=0;
CryptEncrypt(hKey, 0, true, 0, NULL, &encryptBufferLen, 0); // how much space?
BYTE* encryptionBuffer = (BYTE*)malloc(encryptBufferLen);
memcpy(encryptionBuffer, TestMessage, TestMessageLen); // move for in-place-encrypt
CryptEncrypt(hKey,0,true,0, encryptionBuffer, &bufferlen, encryptBufferLen );

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

У вас есть CryptEncrypt (hKey, 0, true, 0, NULL, & encryptBufferLen, 0); // но зачем "NULL", когда вам действительно нужно передать в буфер, содержащий строку для шифрования, чтобы он мог определить размер и вернуть его вам! Затем вы можете двигаться дальше с остальными. Я знаю, как работает бит экспорта (потому что вы работаете с ключами в этом контексте), тогда как здесь вы имеете дело с реальным сообщением. Попробуйте передать параметр и посмотрите, как это происходит?

Я думаю, вы обнаружите, что вы на самом деле не можете расшифровать оба ключа, поскольку вы еще ничего не зашифровали ???? Я думаю, что вы зашифровали сообщение в буфер нулевого размера.

Как я уже сказал, не эксперт, но для меня это выглядит неправильно ... Самое странное, что я нашел ваш пост на днях и собрал рабочие фрагменты, чтобы помочь мне понять его, поэтому я очень надеюсь, что эта информация поможет вам!

0 голосов
/ 22 июля 2013
0 голосов
/ 15 апреля 2011

Я не полностью понимаю ваш запрос. Но в целом

  1. Вы не шифруете данные напрямую с помощью открытого ключа.

  2. Во время шифрования: вы используете сеансовый / симметричный / закрытый ключ для шифрования данных. Этот сеансовый ключ затем шифруется открытым ключом AT_EXCHANGE.

  3. Во время расшифровки: закрытый ключ AT_EXCHANGE расшифрует ключ сеанса. В свою очередь, этот ключ сеанса будет использоваться для расшифровки фактических данных.

...