Тройное шифрование DES

Обратите внимание, что у меня возникла проблема с ключом size. Сначала, основываясь на комментариях, включенных в приведенный ниже код, я решил, что мой ключ должен быть 24 байта (192 бита). Это не сработало, поэтому я попробовал 16, 32 и 8-байтовые ключи — похоже, ничего не работает. Под «не работает» я подразумеваю, что после того, как мой текст был зашифрован и расшифрован, он не имеет того же значения, что и исходный текст.

Пример:

Исходный текст: 'Example test this should work '

Зашифрованный текст: ¸¹pÕô6

Расшифрованный текст: 'Example '

Вот две функции, которые я использую (функции шифрования/дешифрования). Также я укажу, как я вызываю каждую функцию.

        // 168-bit (three-key) 3DES (Triple-DES) encrypt a single 8-byte block (ECB mode)
        // plain-text should be 8-bytes, key should be 24 bytes.
        public byte[] TripleDesEncryptOneBlock(byte[] plainText, byte[] key)
        {
            // Create a new 3DES key.
            TripleDESCryptoServiceProvider des = new TripleDESCryptoServiceProvider();

            // Set the KeySize = 192 for 168-bit DES encryption.
            // The msb of each byte is a parity bit, so the key length is actually 168 bits.

            des.KeySize = 192;
            des.Key = key;
            des.Mode = CipherMode.ECB;
            des.Padding = PaddingMode.None;

            ICryptoTransform ic = des.CreateEncryptor();

            byte[] enc = ic.TransformFinalBlock(plainText, 0, 8);

            return enc;
        }

        public byte[] TripleDesDecryptBlock(byte[] plainText, byte[] key)
        {
            // Create a new 3DES key.
            TripleDESCryptoServiceProvider des = new TripleDESCryptoServiceProvider();

            // Set the KeySize = 192 for 168-bit DES encryption.
            // The msb of each byte is a parity bit, so the key length is actually 168 bits.
            des.KeySize = 192;
            des.Key = key;
            des.Mode = CipherMode.ECB;
            des.Padding = PaddingMode.None;

            ICryptoTransform ic = des.CreateDecryptor();

            byte[] dec = ic.TransformFinalBlock(plainText, 0, 8);

            return dec;
        }

// Encrypt Text
textBox5.Text = ByteToString(TripleDesEncryptOneBlock(StringToByte(textBox5.Text), StringToByte("1 2 3 4 5 6 7 8 9 1 1 2 ")));

// Decrypt Text
textBox5.Text = ByteToString(TripleDesDecryptBlock(StringToByte(textBox5.Text), StringToByte("1 2 3 4 5 6 7 8 9 1 1 2 ")));

Спасибо за любую помощь,

Эван


person Community    schedule 09.08.2011    source источник
comment
Не решает вашу проблему, но CipherMode.ECB кажется мне забавным, учитывая веб-сайт... codinghorror.com/blog/2009/05/   -  person Jarrett Meyer    schedule 09.08.2011
comment
К чему ты тут...?   -  person    schedule 09.08.2011


Ответы (3)


Подсказка кроется в названии используемой вами функции: TripleDesEncryptOneBlock

Этот метод шифрует только один блок входной строки (8 байт или 64 бита). Чтобы зашифровать всю строку, вам нужно связать несколько вызовов этого метода.

person Andrew Cooper    schedule 09.08.2011
comment
Кажется очень странным, что мне пришлось бы вызывать этот метод несколько раз. Есть ли способ изменить этот код, чтобы мне не нужно было это делать? - person ; 09.08.2011
comment
Цель состоит в том, чтобы вы могли реализовать различные методы цепочки, такие как CBC или CFB. - person Andrew Cooper; 09.08.2011
comment
Как правильно вызвать эту функцию в блоках по 8? Не могли бы вы помочь мне с этим? Должен ли я просто разделить данные на 8-байтовые фрагменты и вызвать их? - person ; 09.08.2011

Использовать это:

byte[] enc = ic.TransformFinalBlock(plainText, 0, plainText.Length);

Я надеюсь, что он зашифрует/расшифрует всю вашу строку. Также вам не нужно будет вызывать этот метод несколько раз

person Shivam    schedule 12.12.2012

Ваша проблема здесь:

byte[] dec = ic.TransformFinalBlock(plainText, 0, 8);
                                                  ^

вы кодируете только первые 8 символов вашего массива. Поэтому при декодировании нужно декодировать только эти 8 символов, что приводит к 'Example '.

если вы хотите закодировать весь свой текст, вам нужно увеличить это значение. Но будьте осторожны, если вы используете PaddingMode.None, произойдет сбой, если длина массива, который нужно закодировать, не кратна 8.

Я добавил некоторые отступы к моему тексту следующим образом:

int length = plainText.Length / 8;
if(plainText.Length%8 > 0)
{
    length++;
}
byte[] paddedText = new byte[length * 8];
plainText.CopyTo(paddedText, 0);
byte[] enc = ic.TransformFinalBlock(paddedText, 0, length * 8);
person Th3NetForc3    schedule 19.03.2020