Тройная реализация DES с помощью DES

Я пытаюсь реализовать 3Des с помощью API DES, как показано ниже:

des(input, output, key, mode)

вход, выход и ключ по 8 байт каждый, а режим определяет тип шифрования и дешифрования. Мне интересно, возможно ли иметь алгоритм 3Des с переменной длиной вывода?

Это код, который я написал на C для создания 3des с ключом более 8 байт с помощью этого API.

Но я понятия не имею, работает ли он нормально или можно ли изменить выходные байты.

unsigned char TripleDes(uchar *input, uchar *output,uchar *deskey, int mode)
{
    uchar tt[100];
    uchar tmpInput[100];
    uchar tmpOutput[100];
    int i=0, j=0;

    memset(tt, 0, sizeof(tt));
    memset(tmpInput, 0, sizeof(tmpInput));
    memset(tmpOutput, 0, sizeof(tmpOutput));

    j =  strlen(input);
    memcpy(tmpInput, input, j);
    while(j/8!=0){
        j-=8;
        if (mode) { //Encrypt
            des(tmpInput+i*8, tmpOutput+i*8, deskey,1);
            des(tmpOutput+i*8, tt, deskey+8, 0);
            des(tt,tmpOutput+i*8, deskey, 1);
        }
        else { //Decrypt
            des(tmpInput+i*8, tmpOutput+i*8, deskey, 0);
            des(tmpOutput+i*8, tt, deskey+8, 1);
            des(tt, tmpOutput+i*8, deskey, 0);
        }
        i++;
    }

    strcpy(output, tmpOutput);
    return;
}

Любая идея?


person user5545578    schedule 07.05.2017    source источник
comment
Существуют тестовые векторы для Triple DES. Сначала проверьте свою реализацию по ним.   -  person Artjom B.    schedule 07.05.2017
comment
Мне интересно, возможно ли иметь алгоритм 3Des с переменной длиной вывода? - Кажется, вы пытаетесь реализовать режим работы поверх Triple DES. DES и Triple DES — это блочные шифры, которые работают только с 64-битными блоками. Ни больше ни меньше. Если вы хотите обрабатывать входные данные произвольного размера, вам нужно подумать о режиме работы и схеме заполнения.   -  person Artjom B.    schedule 07.05.2017
comment
Похоже, вы реализовали вариант 3DES с двумя ключами в режиме ECB с неизвестной схемой заполнения. Этот код может считывать неинициализированную память, потому что вы не учли заполнение. Кроме того, не используйте функции str* для двоичных данных, потому что \0 может появиться где угодно, а не только в конце.   -  person Artjom B.    schedule 07.05.2017
comment
Спасибо, что нашли время. У вас есть идеи, как я могу использовать режим CBC в этом подходе?   -  person user5545578    schedule 07.05.2017


Ответы (2)


Наконец-то я смог решить эту проблему не с помощью этого API, а с помощью методов, упомянутых в классе по ссылке ниже:

https://github.com/petricek/eternity-service/blob/master/Common/RSARef/source/desc.c

Мне нужен был тройной класс в режиме CBC с длиной ключа 16. Я изменил эти классы, и они отлично работают:

 DES3_CBCInit
    {
     .....
      deskey(context->subkeys[0], key, encrypt);
      deskey(context->subkeys[1], &key[8], !encrypt);
    }

 DES3_CBCUpdate
  {
    .....

    DESFunction (work, context->subkeys[0]);
    DESFunction (work, context->subkeys[1]);
    DESFunction (work, context->subkeys[0]);

    ......
   }
person user5545578    schedule 08.05.2017

des(tmpInput+i*8, tmpOutput+i*8, deskey,1); // step1: encrypting 8 bytes of input with first 8 bytes of key
des(tmpOutput+i*8, tt, deskey+8, 0);// step2: decrypting result of step1 with last 8 bytes of key
des(tt,tmpOutput+i*8, deskey, 1);// step3: encrypting result of step2 with first 8 bytes of key

Предполагая, что вы использовали 16-байтовый ключ, и если des api делает то, что я упомянул в комментариях, он правильно выполняет 3DES.

Длина выходных данных такая же, как и входных данных, если входные данные кратны 8 байтам. Если длина входных данных не кратна 8, они дополняются конечными нулями, чтобы сделать их кратными 8, а затем шифруются, например, если длина ваших входных данных равна 10, длина выходных данных будет 16

person Pras    schedule 07.05.2017
comment
Спасибо, что нашли время. Это правильно, но иногда мне нужно сгенерировать MAC длиной 8 байтов из, например, 40-байтовых данных, а иногда я хочу зашифровать 16 байтов данных и иметь 16 зашифрованных байтов в режиме CBC. - person user5545578; 07.05.2017
comment
Если длина входных данных не кратна 8, они дополняются нулями в конце, чтобы сделать их кратными 8. Откуда вы это знаете? Заполнение здесь не является частью кода. Он просто берет любые байты из неинициализированной памяти и обрабатывает их как заполнение, которым не является. - person Artjom B.; 07.05.2017
comment
Во втором абзаце я упоминаю, что общая практика состоит в том, чтобы дополнять конечными нулями, чтобы разделить все данные на 8-байтовые блоки. - person Pras; 07.05.2017
comment
Обычно используется заполнение PKCS#7, а не пустое заполнение. Также нулевое заполнение нельзя использовать с двоичными данными. - person zaph; 07.05.2017