Расшифровка DES с помощью OpenSSL

Я пытаюсь расшифровать зашифрованный DES файл из внешнего источника с известным ключом и IV, используя OpenSSL (другие библиотеки на самом деле не вариант, поскольку приложение уже ссылается на него, и я не хочу вводить новые зависимости ). Это приложение Qt, поэтому данные входят и выходят как QByteArrays.

Вот код, который у меня есть на данный момент (настроен на запись расшифрованных данных в файл для проверки):

AmzHandler::AmzHandler(QByteArray encoded)
{
    QByteArray encrypted = QByteArray::fromBase64(encoded);
    QByteArray decrypted = decrypt(encrypted);
    QFile fred ("decrypted");
    fred.open(QFile::WriteOnly);
    fred.write(decrypted);
    fred.close();
}

QByteArray AmzHandler::decrypt(QByteArray encrypted)
{
    DES_cblock key = {0x29, 0xab, 0x9d, 0x18, 0xb2, 0x44, 0x9e, 0x31};
    DES_cblock iv = {0x5e, 0x72, 0xd7, 0x9a, 0x11, 0xb3, 0x4f, 0xee};
    DES_key_schedule schedule;
    unsigned char decrypted[encrypted.size()];

    DES_set_odd_parity(&key);
    DES_set_key_checked(&key, &schedule);

    DES_ncbc_encrypt((unsigned char * )encrypted.constData(), (unsigned char * )decrypted, encrypted.size(), &schedule, &iv, DES_DECRYPT);

    return QByteArray::fromRawData((char * )decrypted, length);
}

Выходной файл для моих тестовых входных данных - ерунда и не согласован при нескольких запусках. (У меня есть работающая реализация на Python, которая прилагается в конце этого сообщения, чтобы проверить ее.) Я не совсем уверен, что происходит; сделал ли я простую ошибку при преобразовании в char или неправильно использую OpenSSL.

РЕДАКТИРОВАТЬ: Решено. Оказывается, строчка DES_set_odd_parity(&key); отсутствовала. Добавьте это, и он работает.

Вот рабочий код на Python:

def AmzHandler(encoded):
    encrypted = base64.b64decode(encoded)
    d = pyDes.des(hex_to_str("29AB9D18B2449E31"), mode=pyDes.CBC, IV=hex_to_str("5E72D79A11B34FEE"))
    decrypted = d.decrypt(encrypted)
    f = open("decrypted-py", "w")
    f.write(decrypted)
    f.close()

person Sam    schedule 22.10.2011    source источник
comment
Выглядит подозрительно: unsigned char *decrypted[encrypted.size()];. Это должен быть указатель или массив.   -  person vhallac    schedule 23.10.2011
comment
@vhallac Хорошо. Теперь я пробовал как unsigned char decrypted[encrypted.size()];, так и (следуя this) unsigned char *decrypted; decrypted = (unsigned char *) malloc (encrypted.size());. Оба производят вывод разного размера, но по-прежнему имеют порядок сотен байтов и, по-видимому, неверны.   -  person Sam    schedule 23.10.2011
comment
QByteArray, вероятно, потребуется длина массива. Невозможно определить это только по адресу буфера.   -  person vhallac    schedule 23.10.2011
comment
@vhallac А, ладно. Я изменил его, чтобы использовать QByteArray :: fromRawData (), который принимает аргумент для размера данных, которые он читает. Однако вывод по-прежнему бессмысленен (какой бы вариант дешифрованного объявления я не использовал).   -  person Sam    schedule 23.10.2011
comment
Остальной код выглядит нормально. Я бы дважды проверил ключ на вашем месте. Вы также можете попробовать дважды проверить свой код, зашифровав его самостоятельно, чтобы убедиться, что он действительно может расшифровать до этого.   -  person vhallac    schedule 23.10.2011
comment
@vhallac Ключ правильный; как я уже сказал, приложенный код Python прекрасно расшифровывает файл. Тогда я попробую поиграть и с шифрованием. Изменить: вывод вообще не согласован для нескольких прогонов, поэтому я не думаю, что что-то записывается в расшифровку ...   -  person Sam    schedule 23.10.2011
comment
@indiv Эх, извините, я хотел это сделать, но он не позволит вам ответить на свой вопрос, пока не пройдет какое-то время, а затем я забыл. Делаешь сейчас.   -  person Sam    schedule 27.10.2011


Ответы (1)


Проблема заключалась в отсутствии вызова DES_set_odd_parity(&key);, который, по-видимому, необходим для правильного декодирования с помощью этой реализации. Рабочий код выглядит следующим образом:

QByteArray AmzHandler::decrypt(QByteArray encrypted)
{
    DES_cblock key = {0x29, 0xab, 0x9d, 0x18, 0xb2, 0x44, 0x9e, 0x31};
    DES_cblock iv = {0x5e, 0x72, 0xd7, 0x9a, 0x11, 0xb3, 0x4f, 0xee};
    DES_key_schedule schedule;
    unsigned char decrypted[encrypted.size()];

    DES_set_odd_parity(&key);
    DES_set_key_checked(&key, &schedule);

    DES_ncbc_encrypt((unsigned char * )encrypted.constData(), (unsigned char * )decrypted, encrypted.size(), &schedule, &iv, DES_DECRYPT);

    return QByteArray::fromRawData((char * )decrypted, length);
}
person Sam    schedule 26.10.2011