Проблема с CryptoApi в С++

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by ShkiperLol, 30 Jun 2010.

  1. ShkiperLol

    ShkiperLol Banned

    Joined:
    17 Apr 2010
    Messages:
    182
    Likes Received:
    1
    Reputations:
    0
    Помогите плиз,уже даже и незнаю что делать.Возникла такая проблема.В моем проекте я получаю ключ которым шифрую из хеша введеного мной пароля,функцией CryptDeriveKey().Выбор алгоритма шифрования и хеширования предоставляеться пользывателю.DES,RC2,RC4,MD5,SHA
    ,MD2,MD4.Так вот шифрование просиходит успешно,независимо от выбраных алгоритмов.А вот расшифровка нормально работает только с алгоритмом RC4.Во всех других случаях функция
    CryptDecrypt возвращает NTE_BAD_DATA.
    В МСДН сказано что ето связано с размером буфера.
    Я размер буфера получал через strlen();попробывал через sizeof();тогда расшифровывает,но в расшифрованой строке еще куча лишних байт.

    Помогите пожалуйста!Я уже все перерыл.все что только можна было перерыть.
     
    #1 ShkiperLol, 30 Jun 2010
    Last edited: 30 Jun 2010
  2. POS_troi

    POS_troi Elder - Старейшина

    Joined:
    1 Dec 2006
    Messages:
    1,569
    Likes Received:
    466
    Reputations:
    108
    Очисти буфер перед использованием

    В windows.h есть ZeroMemory(buffer,size)
     
  3. ShkiperLol

    ShkiperLol Banned

    Joined:
    17 Apr 2010
    Messages:
    182
    Likes Received:
    1
    Reputations:
    0
    он пустой
     
  4. ShkiperLol

    ShkiperLol Banned

    Joined:
    17 Apr 2010
    Messages:
    182
    Likes Received:
    1
    Reputations:
    0
    Очистил,все таже ошибка.
     
  5. POS_troi

    POS_troi Elder - Старейшина

    Joined:
    1 Dec 2006
    Messages:
    1,569
    Likes Received:
    466
    Reputations:
    108
    Читал?
    http://www.rsdn.ru/article/crypto/usingcryptoapi.xml

    Ща нет доступа к С++ =(
     
  6. ShkiperLol

    ShkiperLol Banned

    Joined:
    17 Apr 2010
    Messages:
    182
    Likes Received:
    1
    Reputations:
    0
    Да читал,в шухляде лежит ета распечатка.Но в той статье не используеться функция CryptDerieKey.Вобщем немогу понять почему с RC4 все норм,а с остальными алгоритмами ничего не выходит расшифровать.
     
  7. POS_troi

    POS_troi Elder - Старейшина

    Joined:
    1 Dec 2006
    Messages:
    1,569
    Likes Received:
    466
    Reputations:
    108
    Ну я бы помог , у меня есть наработки по всем функциям КриптАпи , но они все на ноуте а ноут в железном каматозе =(

    Думаю под Утро люди подтянутся и там может кто помнит.
     
  8. ShkiperLol

    ShkiperLol Banned

    Joined:
    17 Apr 2010
    Messages:
    182
    Likes Received:
    1
    Reputations:
    0
    Может быть ты в отрывке кода чтото заметиш неправильное?

    Ета кнопка расшифровывает.
    Code:
    void __fastcall TForm1::Button2Click(TObject *Sender)
    {
     if(Form1->RadioButton1->Checked)
       {
        hs=CALG_MD5;
       }
      if(Form1->RadioButton3->Checked)
       {
        hs=CALG_MD4;
       }
      if(Form1->RadioButton2->Checked)
       {
        hs=CALG_MD2;
       }
      if(Form1->RadioButton4->Checked)
       {
        hs=CALG_SHA;
       }
    
     if(Form1->RadioButton5->Checked)
       {
        alg=CALG_AES;
       }
      if(Form1->RadioButton7->Checked)
       {
        alg=CALG_RC4;
       }
       if(Form1->RadioButton6->Checked)
       {
        alg=CALG_DES;
       }
       if(Form1->RadioButton8->Checked)
       {
        alg=CALG_RC2;
       }
     HCRYPTPROV prov;
     HCRYPTKEY key;
     HCRYPTHASH hash;
     HCRYPTKEY pkey,nkey;
     DWORD count=0;
     char data[100];
     BYTE*gethash;
     int hlen=0;
     strcpy(data,"");
     strcpy(data,Form1->Edit3->Text.c_str());
     DWORD dlen=sizeof(data);
     char pass[100];
     BYTE*dat;
     strcpy(pass,Form1->Edit2->Text.c_str());
     DWORD len=strlen(pass);
     CryptAcquireContext(&prov,"test",NULL,PROV_RSA_FULL,NULL);
     CryptCreateHash(prov,hs,NULL,NULL,&hash);
     CryptHashData(hash,pass,len,NULL);
     CryptDeriveKey(prov,alg,hash,NULL,&key);
     CryptDecrypt(key,NULL,false,NULL,data,&dlen);
    
     Form1->Edit1->Text=data;
    
    }
     
  9. slesh

    slesh Elder - Старейшина

    Joined:
    5 Mar 2007
    Messages:
    2,702
    Likes Received:
    1,224
    Reputations:
    455
    Народ, вы основ наверное не понимаете. Основ работы со строками и данными. Которые расписаны почти везде.
    sizeof - вернет размер буфера. Если буфер выделил на 1024 байта и поместил туда 1000 байт, то на выходе тебе всё равно будет размер буфера
    strlen - вернет кол-во символов, до первого символа с кодом ноль. по этому она подходит тока для текстовых строк. Ну или на интерпритируемых языках.
    Когда шифруешь, то ты можешь узнать сколько байт получилось на выходе и потом уже сохранить это значение, чтобы в дальнейшем знать сколько расшифровывать.

    P.S. MD* и SHA это не шифрование, а хеш функции. И расшифровываться они не могут.
     
    #9 slesh, 1 Jul 2010
    Last edited: 1 Jul 2010
  10. ShkiperLol

    ShkiperLol Banned

    Joined:
    17 Apr 2010
    Messages:
    182
    Likes Received:
    1
    Reputations:
    0
    Читай самый первый пост в верху.На основе хеша полученого из MD и SHA я получаю ключ,которым и шифрую.
    Снова читай самый первый пост.
     
  11. slesh

    slesh Elder - Старейшина

    Joined:
    5 Mar 2007
    Messages:
    2,702
    Likes Received:
    1,224
    Reputations:
    455
    2 ShkiperLol это ты вчитайся в том, что я написал. ни sizeof ни strlen никогда тебе не вернут правильно кол-во данных. тебе его надо запоминать при шифровании.

    Или как вариант - самое простое - тупо храни размер данных первоначальный. чтобы потом если что, то отрезать лишнее. 4 байта сохранить не так сложно
    К томуже обрати внимание на то что некоторые алгоритмы являются блочные. И как не крути, данных будет больше на выходе чем на входе. по этому запоминай размер.
     
    #11 slesh, 1 Jul 2010
    Last edited: 1 Jul 2010
  12. ShkiperLol

    ShkiperLol Banned

    Joined:
    17 Apr 2010
    Messages:
    182
    Likes Received:
    1
    Reputations:
    0
    strlen какраз вернет размер,а sizeof(если б ты почитал что я выше писал)я вставил чтоб посотреть расшифрует ли оно хотяб с мусором,sizeof я использывать вобще не собирался.
    Ето конешно харашо,но ето не вариант.Так как шифроваться у меня будет очень много различных строк.И вобще все ето будет храниться в ресурсах приложения.и если я там буду сохранять размер полученый при шифровании,то я зделаю программу более уязвимой.
     
  13. slesh

    slesh Elder - Старейшина

    Joined:
    5 Mar 2007
    Messages:
    2,702
    Likes Received:
    1,224
    Reputations:
    455
    более уязвимой ты её не сделаешь это уж точно. потому что то по любому можно определить блок данных для расшифровки. А так просто в начало шифрованных данных добавляешь 4 байта размера и всё. можешь и их какнить слегка скрыть
     
  14. ShkiperLol

    ShkiperLol Banned

    Joined:
    17 Apr 2010
    Messages:
    182
    Likes Received:
    1
    Reputations:
    0
    Похоже что так и прийдеться делать.
     
    #14 ShkiperLol, 1 Jul 2010
    Last edited: 1 Jul 2010
  15. ShkiperLol

    ShkiperLol Banned

    Joined:
    17 Apr 2010
    Messages:
    182
    Likes Received:
    1
    Reputations:
    0
    Всеравно не работает,теперь не всю строку расшифровывает.