Модераторы: Poseidon
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> [С++]нужна помощь в реализации RSA 2048 CryptoApi 
:(
    Опции темы
darklight131080
  Дата 3.7.2012, 20:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



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

Листинг взят с этого форума, что надо сделать что бы модернизировать его под  RSA 2048 ?

Листинг довольно объёмный 


Код

#include <Windows.h>
#include <WinCrypt.h>
#include <stdio.h>
#pragma comment (lib, "advapi32.lib")
struct RSAPubKey1024
{
  PUBLICKEYSTRUC publickeystruc;
  RSAPUBKEY rsapubkey;
  BYTE modulus[1024/8];
};
struct RSAPrivKey1024
{
  struct RSAPubKey1024 pubkey;
  BYTE prime1[1024/16];
  BYTE prime2[1024/16];
  BYTE exponent1[1024/16];
  BYTE exponent2[1024/16];
  BYTE coefficient[1024/16];
  BYTE privateExponent[1024/8];
};
struct RSA1024KeyExchBLOB
{
  PUBLICKEYSTRUC publickeystruc;
  ALG_ID algid;
  BYTE encryptedkey[1024/8];
};
#define BUFFER_SIZE (1<<14)
typedef struct
{
  struct RSA1024KeyExchBLOB kb;
  unsigned __int64 fSize;
} EncFileHeader;
void ProcessFile(char *_InFile, char *_OutFile, char *_KeyFile, char Type)
{
  HCRYPTPROV hProv;
  HANDLE hInFile;
  BOOL success = TRUE;
  if( !CryptAcquireContext( &hProv, NULL, MS_ENHANCED_PROV,PROV_RSA_FULL, 0) ) //получаем контекст
  {
    puts( "Не удается получить контекст\n" );
    return;
  }
  if( (hInFile = CreateFileA( _InFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL)) != INVALID_HANDLE_VALUE ) //открываем входной файл
  {
    HANDLE hOutFile;
    if( (hOutFile = CreateFileA( _OutFile, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, 0, NULL)) != INVALID_HANDLE_VALUE ) //открываем выходной файл
    {
      HANDLE hKeyFile;
      if( (hKeyFile = CreateFileA( _KeyFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL)) != INVALID_HANDLE_VALUE ) //открываем файл с публичным ключом
      {
        struct RSAPubKey1024 key;
        DWORD dwLen;
        if( ReadFile( hKeyFile, &key, sizeof(struct RSAPubKey1024), &dwLen, NULL) ) //читаем публичный ключ
        {
          HCRYPTKEY hPubKey;
          if( CryptImportKey( hProv, (BYTE *) &key, sizeof(struct RSAPubKey1024), NULL, 0, &hPubKey)) //и импортируем его
          {
            HCRYPTHASH hHash;
            if( CryptCreateHash( hProv, CALG_MD5, 0, 0, &hHash) ) //создаем хэш
            {
              switch(Type)
              {
                case 'e':
                {
                  HCRYPTKEY hKey;
                  EncFileHeader fh;
                  if( !CryptGenKey( hProv, CALG_3DES, CRYPT_EXPORTABLE, &hKey) ) //генерируем ключ для 3DES
                  {
                    puts( "Не удается создать ключ 3DES\n" );
                    break;
                  }
                  dwLen = sizeof(struct RSA1024KeyExchBLOB);
                  if( CryptExportKey( hKey, hPubKey, SIMPLEBLOB, 0, (BYTE *) &fh.kb, &dwLen) ) //экспортируем ключ 3DES
                  {
                    DWORD dwSzHigh, dwSzLow = GetFileSize( hInFile, &dwSzHigh); //получаем размер исходного файла
                    unsigned __int64 fSize = (dwSzHigh << 32) + dwSzLow;
                    fh.fSize = fSize;
                    if( WriteFile( hOutFile, &fh, sizeof(EncFileHeader), &dwLen, NULL) ) //пишем ключ и размер исходного файла
                    {
                      BYTE buf[BUFFER_SIZE+8]; //8 - запас на padding
                      while( fSize )
                      {
                        if( !ReadFile( hInFile, buf, BUFFER_SIZE, &dwLen, NULL) ) //читаем блок данных
                        {
                          puts( "Ошибка чтения файла\n" );
                          break;
                        }
                        dwSzLow = dwLen;
                        if( !CryptEncrypt( hKey, hHash, fSize <= BUFFER_SIZE, 0, buf, &dwSzLow, sizeof(buf)) ) //шифруем и хешируем его
                        {
                          puts( "Ошибка шифрования\n" );
                          break;
                        }
                        if( !WriteFile( hOutFile, buf, dwSzLow, &dwSzLow, NULL) )
                        {
                          puts( "Ошибка записи\n" );
                          break;
                        }
                        fSize -= dwLen;
                      }
                      if( !fSize ) //все зашифровали нормально
                      {
                        dwLen = sizeof(buf);
                        if( CryptSignHash( hHash, AT_KEYEXCHANGE, NULL, 0, buf, &dwLen) ) //подписываем хэш
                        {
                          if( !WriteFile( hOutFile, buf, dwLen, &dwLen, NULL) )
                            puts( "Ошибка записи хеша в файл\n" );
                          else
                            puts( "Шифрование успешно завершено\n" );
                        }
                        else
                          puts( "Не удается подписать файл\n" );
                      }
                    }
                    else
                      puts( "Не удается сохранить ключ 3DES\n" );
                  }
                  else
                    puts( "Не удается экспортировать ключ 3DES\n" );
                  CryptDestroyKey( hKey );
                  break;
                }
                case 'd':
                {
                  HCRYPTKEY hPrivKey;
                  EncFileHeader fh;
                  if( !CryptGetUserKey( hProv, AT_KEYEXCHANGE, &hPrivKey) ) //достаем приватный ключ пользователя
                  {
                    puts( "Не удается получить приватный ключ из контейнера\n" );
                    break;
                  }
                  if( ReadFile( hInFile, &fh, sizeof(fh), &dwLen,NULL) )
                  {
                    HCRYPTKEY hKey;
                    if( CryptImportKey( hProv, (BYTE *) &fh.kb, sizeof(struct RSA1024KeyExchBLOB), hPrivKey, 0, &hKey) ) //импортируем сессионный ключ
                    {
                      unsigned __int64 fOrgSize = fh.fSize, fEncSize;
                      DWORD dwSzLow, dwSzHigh;
                      BYTE buf[BUFFER_SIZE];
                      dwSzLow = GetFileSize( hInFile, &dwSzHigh);
                      fEncSize = (dwSzHigh << 32) + dwSzLow - sizeof(EncFileHeader) - 1024/8; //размер зашифрованных данных
                      while( fEncSize )
                      {
                        if( !ReadFile( hInFile, buf, fEncSize >= BUFFER_SIZE ? BUFFER_SIZE : (DWORD)fEncSize, &dwLen, NULL) )
                        {
                          puts( "Ошибка чтения\n" );
                          break;
                        }
                        dwSzLow = dwLen;
                        if( !CryptDecrypt( hKey, hHash, fEncSize <= BUFFER_SIZE, 0, buf, &dwSzLow) ) //расшифровываем данные
                        {
                          puts( "Ошибка дешифрования\n" );
                          break;
                        }
                        if( !WriteFile( hOutFile, buf, fOrgSize >= dwSzLow ? dwSzLow : (DWORD) fOrgSize, &dwSzLow, NULL) )
                        {
                          puts( "Ошибка записи\n" );
                          break;
                        }
                        fEncSize -= dwLen;
                        fOrgSize -= dwSzLow;
                      }
                      if( !fEncSize ) //все нормально отработалось
                      {
                        if( ReadFile( hInFile, buf, 1024/8, &dwLen, NULL) && dwLen == 1024/8 ) //читаем подпись
                        {
                          if( !CryptVerifySignature( hHash, buf, 1024/8, hPubKey, NULL, 0) )
                            puts( "Ошибка проверки подписи. Возможно файл был поврежден\n" );
                          else
                            puts( "Файл успешно расшифрован\n" );
                        }
                        else
                          puts( "Не найдена сигнатура файла\n" );
                      }
                      CryptDestroyKey( hKey );
                    }
                    else
                      puts( "Не удается импортировать ключ шифрования\n" );
                  }
                  else
                    puts( "Ошибка чтения файла\n");
                  CryptDestroyKey( hPrivKey );
                }
              }
              CryptDestroyHash(hHash);
            }
            else
              puts( "Не удается создать хэш\n" );
            CryptDestroyKey( hPubKey );
          }
          else
            puts( "Не удается импортировать открытый ключ\n" );
        }
        else
          puts( "Не удается прочитать файл с публичным ключем\n" );
        CloseHandle( hKeyFile );
      }
      else
        puts( "Не удается открыть файл с публичным ключем\n" );
      CloseHandle( hOutFile );
    }
    else
      puts("Не удается открыть выходной файл\n");
    CloseHandle(hInFile);
  }
  else
    puts( "Не удается открыть входной файл\n" );
  CryptReleaseContext( hProv, 0);
}
void GenerateKey()
{
  HCRYPTPROV hProv;
  HCRYPTKEY hKey;
  if( !CryptAcquireContext( &hProv, NULL, MS_ENHANCED_PROV, PROV_RSA_FULL, 0) &&
      !CryptAcquireContext( &hProv, NULL, MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_NEWKEYSET) ) //пытаемся открыть существующий keyset или создать новый
  {
    puts( "Не удается создать контекст\n" );
    return;
  }
  if( CryptGenKey( hProv, AT_KEYEXCHANGE, 1024<<16, &hKey) ) //генерируем 1024-битный ключ для обмена
  {
    struct RSAPubKey1024 key;
    DWORD dwLen = sizeof(struct RSAPubKey1024);
    if( CryptExportKey( hKey, NULL, PUBLICKEYBLOB, 0, (BYTE*) &key, &dwLen) ) //экспортируем ключ
    {
      HANDLE hFile;
      if( (hFile = CreateFileA( "key.rsa", GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL)) != INVALID_HANDLE_VALUE )
      {
        if( !WriteFile( hFile, &key, dwLen, &dwLen, NULL) ) //сохраняем файл
          puts( "Не удается сохранить публичный ключ RSA для обмена в файл\n" );
        CloseHandle( hFile );
      }
      else
        puts( "Не удается создать файл pubkey.xch\n" );
    }
    else
      puts( "Не удается экспортировать публичный ключ RSA для обмена\n" );
    CryptDestroyKey(hKey);
  }
  else
    puts( "Не удается создать ключ RSA для обмена\n" );
  CryptReleaseContext( hProv, 0);
}
int main()
{
  GenerateKey();
  ProcessFile("in.bin", "out.bin", "key.rsa", 'e');
  ProcessFile("out.bin", "out_d.bin", "key.rsa", 'd');
  ExitProcess(0);
  return 0;
}



Любые предложения, предположения приветствйются, тупо изменить в сорцах 1024 на 2048 не поможет говорят))  

Может быть изменить цифры + ( CryptGenKey( hProv, AT_KEYEXCHANGE, 0x08000000, &hKey) ) ?

И как узнать что файл зашифрован 2048 bit кеем?


Спасибо всем за внимание!!!

Это сообщение отредактировал(а) darklight131080 - 3.7.2012, 21:10
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Центр помощи"

ВНИМАНИЕ! Прежде чем создавать темы, или писать сообщения в данный раздел, ознакомьтесь, пожалуйста, с Правилами форума и конкретно этого раздела.
Несоблюдение правил может повлечь за собой самые строгие меры от закрытия/удаления темы до бана пользователя!


  • Название темы должно отражать её суть! (Не следует добавлять туда слова "помогите", "срочно" и т.п.)
  • При создании темы, первым делом в квадратных скобках укажите область, из которой исходит вопрос (язык, дисциплина, диплом). Пример: [C++].
  • В названии темы не нужно указывать происхождение задачи (например "школьная задача", "задача из учебника" и т.п.), не нужно указывать ее сложность ("простая задача", "легкий вопрос" и т.п.). Все это можно писать в тексте самой задачи.
  • Если Вы ошиблись при вводе названия темы, отправьте письмо любому из модераторов раздела (через личные сообщения или report).
  • Для подсветки кода пользуйтесь тегами [code][/code] (выделяйте код и нажимаете на кнопку "Код"). Не забывайте выбирать при этом соответствующий язык.
  • Помните: один топик - один вопрос!
  • В данном разделе запрещено поднимать темы, т.е. при отсутствии ответов на Ваш вопрос добавлять новые ответы к теме, тем самым поднимая тему на верх списка.
  • Если вы хотите, чтобы вашу проблему решили при помощи определенного алгоритма, то не забудьте описать его!
  • Если вопрос решён, то воспользуйтесь ссылкой "Пометить как решённый", которая находится под кнопками создания темы или специальным флажком при ответе.

Более подробно с правилами данного раздела Вы можете ознакомится в этой теме.

Если Вам помогли и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, Poseidon, Rodman

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


 




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


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

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