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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> OpenSSL: баг реализации Blowfish 
:(
    Опции темы
Alca
Дата 17.12.2008, 18:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3993
Регистрация: 14.6.2006

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



OpenSSL: баг реализации Blowfish.
Скачал исходники отсюда: openssl-0.9.8i.tar.gz
Заметил, что если шифрую ключем, например:
Код

1111 или 111111 (т.е. все символы одинаковые),

то можно данные расшифровать ключом: 
Код

1
или
11
или
111
и т.д.

Единицы можно заменить на любой символ и всё будет расшифровываться.
Может кто-то сталкивался с этой проблемой?

Это сообщение отредактировал(а) Alca - 17.12.2008, 18:55

Присоединённый файл ( Кол-во скачиваний: 12 )
Присоединённый файл  openssl_0.9.8i_________Blowfish_.zip 51,69 Kb


--------------------
PM WWW ICQ Skype Jabber   Вверх
jonie
Дата 18.12.2008, 08:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 5613
Регистрация: 21.8.2005
Где: Владимир

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



значит не так шифруешь.


--------------------
Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет...
PM MAIL Jabber   Вверх
Alca
Дата 18.12.2008, 09:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3993
Регистрация: 14.6.2006

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



Не спорю.


--------------------
PM WWW ICQ Skype Jabber   Вверх
Alca
Дата 18.12.2008, 15:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3993
Регистрация: 14.6.2006

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



Выкладываю исходники. Если есть критика - буду рад. smile 
Код

#include "openssl-0.9.8i\blowfish.h"
//...    
//---------------------------------------------------------------------------
//TODO: bBlowfishCrypt 
bool bBlowfishCrypt(FILE *pFileIn, FILE *pFileOut, int iMode, const string &сsBlowfishCryptKey) { 
    //-------------------------------------
    //CHECK
    if (NULL == pFileIn || NULL == pFileOut) {
        return false;
    }
    if (!(BF_ENCRYPT == iMode) && !(BF_DECRYPT == iMode) ) {
        return false;
    }
    if (true == сsBlowfishCryptKey.empty()) {
        return false;
    }

    //-------------------------------------
    //переменные
    int                iNum        = 0;
    const unsigned int cuiBuffSize = 1024;
    unsigned char      ucBuffIn [cuiBuffSize];    memset(ucBuffIn,  0, sizeof(unsigned char) * cuiBuffSize);
    unsigned char      ucBuffOut[cuiBuffSize];    memset(ucBuffOut, 0, sizeof(unsigned char) * cuiBuffSize);
      
    //-------------------------------------
    //Ключ шифрования длиной 128 бит и вектор инициализации 
    unsigned char ucIv[8] = {'0', '1', '2', '3', '4', '5', '6', '7'};    //memset(ucIv, 0, sizeof(unsigned char) * 8);

    size_t uiKeySize = sizeof(unsigned char) * сsBlowfishCryptKey.size();
    unsigned char *pucKey = (unsigned char *)malloc(uiKeySize);
    if (pucKey == NULL) {
        return false;
    }
    memset(pucKey, 0, uiKeySize);

    if (false == bStrToUCHAR(сsBlowfishCryptKey, pucKey, сsBlowfishCryptKey.size())) {
        /*LOG*/Console.bWriteErrLine("bStrToUCHAR() == false");
        free(pucKey);    
        pucKey = NULL;

        return false;
    }
      
    //-------------------------------------
    //Помещаем ключ в структуру bfkey
    BF_KEY bfkey;
    BF_set_key(&bfkey, uiKeySize, pucKey);    
    
    free(pucKey);    
    pucKey = NULL;
     
    //-------------------------------------
    //Определяем что за файл (шифр / нешифр)
    switch (iMode) {
        case BF_ENCRYPT:    
            {
             //запись штампа в вых. файл
                size_t uiWrited = fwrite(g_ucBlowfishStamp, 1, g_culBlowfishStampSize, pFileOut);
                if (uiWrited != g_culBlowfishStampSize) {
                    /*LOG*/Console.bWriteErrLine("uiWrited != g_culBlowfishStampSize");
                    return false;
                }
                break;
            }
        
        case BF_DECRYPT:    
            {
                //читаем файл начиная с конца штампа
                if (0 != fseek(pFileIn, g_culBlowfishStampSize, SEEK_SET)) {
                    return false;
                }    
                break;    
            }    
    }
    
    //-------------------------------------
    //Шифруем / расшифровуем блоки входного файла
    for (;;) { 
        size_t uiInLen = fread(ucBuffIn, 1, cuiBuffSize, pFileIn); 
        if (uiInLen <= 0) {
            break; 
        }
          
        BF_cfb64_encrypt(ucBuffIn, ucBuffOut, uiInLen, &bfkey, ucIv, &iNum , iMode); 
        
        size_t uiWrited = fwrite(ucBuffOut, 1, uiInLen, pFileOut); 
        if (uiWrited != uiInLen) {
            /*LOG*/Console.bWriteErrLine("uiWrited != uiInLen");
            return false;
        }
    } 

    //-------------------------------------
    //файл шифрован, дописать в конец вых. файла шифрованый ucVerifyStamp
    if (BF_ENCRYPT == iMode) {
        unsigned char ucBuffOut2[g_culVerifyStampSize];        memset(ucBuffOut2, 0, sizeof(ucBuffOut2));
        
        BF_cfb64_encrypt(g_ucVerifyStamp, ucBuffOut2, g_culVerifyStampSize, &bfkey, ucIv, &iNum , iMode); 
        
        size_t uiWrited = fwrite(ucBuffOut2, 1, g_culVerifyStampSize, pFileOut);
        if (uiWrited != g_culVerifyStampSize) {
            /*LOG*/Console.bWriteErrLine("uiWrited != g_culVerifyStampSize");
            return false;
        }
    }
    
    //-------------------------------------
    //файл дешифрован, проверяем что в конце есть ucVerifyStamp
    if (BF_DECRYPT == iMode) {
        //прочитать последние culVerifyStampSize байты
        unsigned char     ucBuffOut3[g_culVerifyStampSize];        memset(ucBuffOut3, 0, sizeof(ucBuffOut3));
        unsigned long int ulFileOutSize = ulFileSize(pFileOut);
        
        if (0 != fseek(pFileOut, ulFileOutSize - g_culVerifyStampSize, SEEK_SET)) {
            return false;
        }
        size_t uiOutLen = fread(ucBuffOut3, 1, g_culVerifyStampSize, pFileOut);
        if (g_culVerifyStampSize != uiOutLen) {
            return false;
        }
        rewind(pFileOut);

        //сравниваем со ucVerifyStamp (0 - equal)
        int iRes = memcmp((const void *)g_ucVerifyStamp, (const void *)ucBuffOut3, g_culVerifyStampSize);
        if (0 != iRes) {
            return false;
        }

        //есть ucVerifyStamp -> удаляем с конца "VerifySignature"
        if (false == bCutFileFromEnd(pFileOut, g_culVerifyStampSize)) {
            return false;
        }            
    }    

    return true; 
}
//...
int main() {
    //...
    //-------------------------------------
    //создаём вх, вых файлы 
    FILE *pFileIn = fopen(sFilePathIn.c_str(), "rb+");
    if (NULL == pFileIn) {
        /*INFO*/Console.bWriteErrLine("Не могу открыть входной файл");
        return false;
    }
    sFilePathOut = sFilePathIn + ".{" + sCreatePlainGUID() + "}";    //добавить расширение ".tmp"
    FILE *pFileOut = fopen(sFilePathOut.c_str(), "wb+");
    if (NULL == pFileOut) {
        /*INFO*/Console.bWriteErrLine("Не могу открыть выходной файл");
        return false;
    }

    //-------------------------------------
    //шифр / дешифр
    bool bIsCrypted = bBlowfishCrypt(pFileIn, pFileOut, iBlowfishCryptMode, сsBlowfishCryptKey); 

    //-------------------------------------
    //закрываем вх, вых файлы
    fflush(pFileOut);    fclose(pFileOut);
    fflush(pFileIn);    fclose(pFileIn);
    //...
}



Это сообщение отредактировал(а) Alca - 26.12.2008, 22:50


--------------------
PM WWW ICQ Skype Jabber   Вверх
Alca
Дата 26.12.2008, 22:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3993
Регистрация: 14.6.2006

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



Нужна помощь. smile 


--------------------
PM WWW ICQ Skype Jabber   Вверх
Alca
Дата 26.12.2008, 23:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3993
Регистрация: 14.6.2006

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



Цитата

значит не так шифруешь.

Вот инициализирую ключ:
Код

BF_KEY bfkey;        memset(&bfkey, 0, sizeof(bfkey));
BF_set_key(&bfkey, uiKeySize, pucKey);
    
А вот его значение после, при таких парольных фразах:
Код

pucKey = "1";
uiKeySize = 1;

и
Код

pucKey = "1111";
uiKeySize = 4;

Результат одинаковый.

Это сообщение отредактировал(а) Alca - 26.12.2008, 23:31

Присоединённый файл ( Кол-во скачиваний: 7 )
Присоединённый файл  Results.zip 18,09 Kb


--------------------
PM WWW ICQ Skype Jabber   Вверх
xvr
Дата 27.12.2008, 13:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

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



А что такое bStrToUCHAR?
PM MAIL   Вверх
Alca
Дата 27.12.2008, 17:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3993
Регистрация: 14.6.2006

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



Код

bool bStrToUCHAR(const std::string &csStr, unsigned char *ucBuff, unsigned int uiBuffLen) {
    for (unsigned int i = 0; i < csStr.size(); i ++)  { 
        ucBuff[i]  = static_cast<unsigned char>(csStr.at(i)); 
    }

    return true;
}



--------------------
PM WWW ICQ Skype Jabber   Вверх
xvr
Дата 27.12.2008, 19:29 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

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



Цитата(Alca @ 26.12.2008,  23:28)
Цитата

значит не так шифруешь.

Вот инициализирую ключ:
Код

BF_KEY bfkey;        memset(&bfkey, 0, sizeof(bfkey));
BF_set_key(&bfkey, uiKeySize, pucKey);
    
А вот его значение после, при таких парольных фразах:
Код

pucKey = "1";
uiKeySize = 1;

и
Код

pucKey = "1111";
uiKeySize = 4;

Результат одинаковый.

Все очень просто, смотрим реализацию BF_set_key:
Код

void BF_set_key(BF_KEY *key, int len, const unsigned char *data)
    {
    int i;
    BF_LONG *p,ri,in[2];
    const unsigned char *d,*end;


    memcpy(key,&bf_init,sizeof(BF_KEY));
    p=key->P;

    if (len > ((BF_ROUNDS+2)*4)) len=(BF_ROUNDS+2)*4;

    d=data;
    end= &(data[len]);
    for (i=0; i<(BF_ROUNDS+2); i++)
        {
        ri= *(d++);
        if (d >= end) d=data;

        ri<<=8;
        ri|= *(d++);
        if (d >= end) d=data;

        ri<<=8;
        ri|= *(d++);
        if (d >= end) d=data;

        ri<<=8;
        ri|= *(d++);
        if (d >= end) d=data;

        p[i]^=ri;
        }
Т.е. исходный пароль раскладывается в поля ключа, длинна этого пароля - (BF_ROUNDS+2)*4 (что равно 72). Если пароль короче, то он повторяется сначала. Так как у тебя пароль состоит из разного числа '1', то в результате получается эквивалентный пароль из 72х единиц, сколько бы изначально ты единиц не подавал  smile Добавь в качестве первого символа в пароль длинну строки с паролем (можно прямо в бинарном виде)

Это сообщение отредактировал(а) xvr - 27.12.2008, 19:30
PM MAIL   Вверх
shara
Дата 28.12.2008, 00:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



как все просто оказалось

xvr smile 


--------------------
   с точки зрения аэродинамики шмель не может летать  
PM MAIL   Вверх
Alca
Дата 29.12.2008, 14:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3993
Регистрация: 14.6.2006

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



Цитата

Добавь в качестве первого символа в пароль длинну строки с паролем (можно прямо в бинарном виде)

Эт как? Пароль не должен состоять из одинаковых символов?

Это сообщение отредактировал(а) Alca - 29.12.2008, 14:37


--------------------
PM WWW ICQ Skype Jabber   Вверх
xvr
Дата 29.12.2008, 15:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

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



Цитата(Alca @ 29.12.2008,  14:35)
Цитата

Добавь в качестве первого символа в пароль длинну строки с паролем (можно прямо в бинарном виде)

Эт как? Пароль не должен состоять из одинаковых символов?

Желательно. И уж точно не должен состоять из N единичек - такой пароль вскроют в секунды.

PM MAIL   Вверх
Alca
Дата 29.12.2008, 15:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3993
Регистрация: 14.6.2006

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



Его еще быстее подберут, если вместо пароля "777777" прокатит "7".
Юзер то наверное не вкурсе про такой прикол. 
Я считаю, что это какая-то глючная реализация BlowFish. 
Чем думали те кто этот код писал? Или это так должно быть по алгоритму? 

Это сообщение отредактировал(а) Alca - 30.12.2008, 10:59


--------------------
PM WWW ICQ Skype Jabber   Вверх
xvr
Дата 29.12.2008, 22:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

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



Цитата(Alca @ 29.12.2008,  15:08)
Его еще быстее подберут, если вместо пароля "777777" прокатит "7".
Юзер то наверное не вкурсе про такой прикол. 
Я считаю, что это какая-то глючная реализация BlowFish. 
Чем думали те кто этот код писал? Или это так долно быть по алгоритму?

Похоже функция BF_set_key не расчитанна на прямую генерацию BF ключа из пароля, она ожидает бинарный ключ.
Цитата из openssl-0.9.8i/doc/ssleay.txt:
Цитата

To generate a password from a text string, I suggest using MD5 (or MD2) to
produce a 16 byte message digest that can then be passed directly to
BF_set_key().

PM MAIL   Вверх
xvr
Дата 29.12.2008, 23:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

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



Посмотрел еще раз исходники - ключ генерируется из пароля в функции EVP_BytesToKey (файл openssl-0.9.8i/crypto/evp/evp_key.c). Действительно используется дайжест и еще что-то, не разбирался - функция не очень тривиальная  smile 
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.0618 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


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

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