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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> RSA Crypt C# и Win32 Crypto API, RSA Crypt C# и Win32 Crypto API 
:(
    Опции темы
Sokil
  Дата 18.8.2010, 13:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Здравствуйте.

Возникла необходимость криптовать данные используя алгоритм RSA на сервере(с#) и на клиенте(с++).
Отдельно в с# и отдельно в с++ криптование работает отлично.

Генерю пару ключей в С# и импортирую открытый ключ в с++, криптую, закриптованые данные передаю обратно в с#.
И пробую декриптовать, выдает ошибку: "Encryption failed.Bad Data.

Подскажите, пожалуйста, в чем может быть проблема?

Код с#(код минимальный, без обработки ошибок):
Код

                RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(512/*key size*/);
                RSAParameters rsaParams = rsa.ExportParameters(false);

                Console.WriteLine("RSA Exponent: {0}", toHexStr(rsaParams.Exponent));
                Console.WriteLine("RSA PublicKey: {0}", toHexStr(rsaParams.Modulus));

                byte[] encryptedData;
                string sEncHex = Console.ReadLine();
                encryptedData = toBytes(sEncHex);

                byte[] decryptedData = rsa.Decrypt( encryptedData, false);


Код с++(код минимальный, без обработки ошибок):
Код

    HCRYPTPROV    hCryptProv = NULL;
    CryptAcquireContext(&hCryptProv, 
                               A2W("1ContainerName"), 
                               MS_DEF_PROV, 
                               PROV_RSA_FULL, 
                   CRYPT_NEWKEYSET);

    //RSA Public Key беру сгенеренный из c#
        char* cPublKeyStr = "DF726C2D8D4D1447C9C6395F4DD96743015DB83D6D5A704D9436D2EDFCDE8105EB8F77E72CC06AAD42769289EE8A5E97A71B2FCD404088C3B17667A96B7C52F7";
    BYTE* pModulus = new BYTE[64];     // Byte array that contains the modulus.
    memset(pModulus, 0, 64);
    DWORD cbModulus = (DWORD)strlen(cPublKeyStr); // Size of the modulus in bytes.
    DWORD dwExponent = 0x10001;   // RSA Exponent

    hexToBA( cPublKeyStr, pModulus, &cbModulus );

    DWORD cbKeyBlob = cbModulus + sizeof(PUBLICKEYSTRUC) + sizeof(RSAPUBKEY);
    BYTE *pBlob = new BYTE[cbKeyBlob];

    PUBLICKEYSTRUC *pPublicKey = (PUBLICKEYSTRUC*)pBlob;
    pPublicKey->bType = PUBLICKEYBLOB; 
    pPublicKey->bVersion = CUR_BLOB_VERSION;  // Always use this value.
    pPublicKey->reserved = 0;                 // Must be zero.
    pPublicKey->aiKeyAlg = CALG_RSA_KEYX;     // RSA public-key key exchange. 

    RSAPUBKEY *pRsaPubKey = (RSAPUBKEY*)(pBlob + sizeof(PUBLICKEYSTRUC));
    pRsaPubKey->magic = RSA1;            // RSA1 0x31415352 Public key.
    pRsaPubKey->bitlen = cbModulus * 8;  // Number of bits in the modulus.
    pRsaPubKey->pubexp = dwExponent;     // Exponent.

    // Copy the modulus into the blob. Put the modulus directly after the
    // RSAPUBKEY structure in the blob.
    BYTE *pKey = (BYTE*)(pRsaPubKey + sizeof(RSAPUBKEY));
    CopyMemory(pKey, pModulus, cbModulus);

    // Now import the key.
    HCRYPTKEY hCryptKey = NULL;  // Receives a handle to the key.
    CryptImportKey(hCryptProv, pBlob, cbKeyBlob, 0, 0, &hCryptKey);

    char* testStr = "test";
    BYTE byteArrayText[ 256 ]; memset(byteArrayText, 0, 256);
    for ( UINT nI = 0; nI < strlen(testStr); ++nI )
        byteArrayText[ nI ] = testStr[ nI ];

    DWORD dwTextLength = (DWORD)strlen(testStr);
    DWORD dwBufferLength = 256;

    CryptEncrypt(        hCryptKey, 
                            0, 
                            true, 
                            CRYPT_OAEP,
                            byteArrayText,
                            &dwTextLength,
                            dwBufferLength );


    wprintf(L"\n\nCryptedText = \"");
    for (UINT i = 0; i < dwTextLength; i++ )
    {
        wprintf(L"%02x",byteArrayText[i]);
    }
    wprintf(L"\n\nCryptedTextReversed = \"");
    for (int i = dwTextLength-1; i >= 0; i-- )
    {
        wprintf(L"%02x",byteArrayText[i]);
    }


НАШЕЛ ПРИЧИНУ:

Неправильно вычислялся указатель на Public Key  в структуре PUBLICKEYBLOB :

Код

 BYTE *pKey = (BYTE*)(pRsaPubKey + sizeof(RSAPUBKEY));


pRsaPubKey здесь указатель на RSAPUBKEY , потому если его увеличить на  12(размер в байтах RSAPUBKEY), то указатель увеличится не на 12 байт, как нужно, в нашем случае, а на 12*sizeof(RSAPUBKEY ) и потому адрес начала ключа будет неправильным.

Правильный код:


Код

 BYTE* pKey = pBlob + sizeof(BLOBHEADER)+ sizeof(RSAPUBKEY); 

Код импорта ключа брал из MSDN, там он с ошибкойhttp://msdn.microsoft.com/en-us/library/dd...28VS.85%29.aspx

Так что, будьте бдительны, не попадайтесь, как я. )


Это сообщение отредактировал(а) Sokil - 1.10.2010, 14:29
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.0831 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


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

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