TripleDES: Указанный ключ является известным слабым ключом для 'TripleDES' и не может использоваться

Автор учебного пособия использует пакет data.table. Как вы можете прочитать здесь , использование with = F иногда используется для получения одного столбца. Убедитесь, что вы загрузили и установили data.table и другие пакеты, чтобы следовать руководству. Также убедитесь, что ваш набор данных является объектом data.table.

12
задан David Chappelle 21 April 2009 в 14:21
поделиться

6 ответов

Вместо использования MACTripleDES с повторяющимся ключом DES для подделки одного DES CBC-MAC, вы можете просто реализовать CBC-MAC самостоятельно поверх DESCryptoServiceProvider ,

<1111111111111111> не является слабым ключом DES.

Это вычислит DES CBC-MAC:

public static byte[] CalcDesMac(byte[] key, byte[] data){
        DESCryptoServiceProvider des = new DESCryptoServiceProvider();
        des.Key = key;
        des.IV = new byte[8];
        des.Padding = PaddingMode.Zeros;
        MemoryStream ms = new MemoryStream();
        using(CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write)){
          cs.Write(data, 0, data.Length);
        }
        byte[] encryption = ms.ToArray();
        byte[] mac = new byte[8];
        Array.Copy(encryption, encryption.Length-8, mac, 0, 8);
        PrintByteArray(encryption);
        return mac;
    }
1
ответ дан 2 December 2019 в 22:05
поделиться

Я бы не рекомендовал это, но вы должны иметь возможность изменять IL-код, который проверяет слабые ключи, используя Reflector и надстройка ReflexIL

править:

Извините, мне потребовалось некоторое время, чтобы загрузить все это на мою виртуальную машину (работающую под управлением Ubuntu), и я не хотел связываться с Mono.

  • Установите надстройку ReflexIL: Просмотр -> Надстройки -> Добавить
  • Откройте ReflexIL: Инструменты -> ReflexIL v0.9
  • Найдите функцию IsWeakKey (). (Вы можете использовать поиск: F3)
  • Появятся две функции, дважды щелкните одну из System.Security.Cryptography.TripleDES
  • ReflexIL тоже должен был появиться. На вкладке «Инструкции» прокрутите вниз до строки 29 (смещение 63).
  • Измените ldc.i4.1 на ldc.i4.0, это означает, что функция всегда будет возвращать false.

На панели сборок (левая) теперь вы можете прокрутить вверх и щелкнуть «Common Language Runtime Library», панель ReflexIL даст вам возможность сохранить ее.

Важные примечания:

  • Сначала создайте резервную копию исходной сборки! (mscorlib.dll)
  • mscorlib.dll - это подписанная сборка, и вам понадобится .NET SDK (инструмент sn.exe) для ReflexIL, чтобы он пропустил проверку. Я только что проверил это сам, у вас уже должен быть установлен Visual C #. Просто нажмите «Зарегистрировать для пропуска проверки (на этом компьютере)», когда вас попросят.
  • Я не думаю, что должен говорить вам использовать это только на вашей машине разработки :)

Удачи! Если вам нужны дополнительные инструкции, пожалуйста, используйте поле для комментариев.

edit2:

Я запуталась!

Я полностью удалил проверку IsWeakKey из функции set_Key в сборке mscorlib. Я абсолютно уверен, что изменил правильную функцию, и что я сделал это правильно. Дизассемблер Reflector больше не показывает чек. Однако забавно то, что Visual C # по-прежнему генерирует то же исключение.

Это наводит меня на мысль, что mscorlib каким-то образом должен быть где-то кэширован. Однако переименование mscorlib.dll в mscorlib.dll_ приводит к сбою MSVC #, поэтому он по-прежнему должен зависеть от исходной dll.

Это довольно интересный материал, но я думаю, что дошел до того момента, когда понятия не имею, что происходит, это просто не имеет никакого смысла! См. Прикрепленное изображение. : (

edit3:

Я заметил в Olly, что в отличие от таких сборок, как mscoree, mscorsec и mscorwks; mscorlib.dll на самом деле не находится в: c: \ WINDOWS \ Microsoft.NET \ Framework \ v2.0.50727 \

Но вместо этого в несуществующем месте: C: \ WINDOWS \ assembly \ NativeImages_v2.0.50727_32 \ mscorlib \ 6d667f19d687361886990f3ca0f49816 \ mscorlib.ni.dll

Я думаю, что здесь что-то упускает :) Разберемся еще немного.

edit4:

Даже после того, как ВСЕ исправили в IsWeakKey и поигрались с удалением и созданием новых образов (x. ni .dll) mscorlib.dll с помощью ngen.exe ", Я получаю то же исключение.Я должен отметить, что даже после удаления родных образов mscorlib он все еще использует mscorlib.ni.dll ... Meh.

Я сдаюсь. Я надеюсь, что кто-нибудь сможет ответить, что, черт возьми, происходит, потому что я точно не знаю. :)

6
ответ дан 2 December 2019 в 22:05
поделиться

К сожалению, поведение нельзя изменить.

1
ответ дан 2 December 2019 в 22:05
поделиться

Я не эксперт по безопасности, но не будет XOR вашего ключа с другим значением будет достаточно для проверки работоспособности ? Вы могли бы сделать это для своей отладочной версии (с надлежащим IFDEF), чтобы вы могли выполнить правильную проверку и удалить ее для своей версии или рабочей версии, где ключ будет достаточно сильным.

0
ответ дан 2 December 2019 в 22:05
поделиться

Я выяснил, что вам нужно сделать. К счастью, есть метод, который создает ICryptoTranforms, который не проверяет слабые ключи. Вам также нужно следить за базовым классом, поскольку он также выполняет проверки работоспособности. Через отражение просто вызовите метод _NewEncryptor (вам нужно сделать немного больше отражения, но это идея).

К счастью, MACTripleDES имеет поле типа TripleDES, поэтому его следует унаследовать от MACTripleDES и заменить его посредством отражения в конструкторах. Я сделал за тебя всю работу.

Я не могу убедиться, что сгенерирован правильный MAC-адрес, но исключения не генерируются. Кроме того, вы можете захотеть прокомментировать код и выполнить обработку исключений (сбои отражения - например, если поля / методы отсутствуют) - но это ТАК; так что я не заморачивался.

using System;
using System.Reflection;
using System.Security.Cryptography;
using System.IO;

namespace DesHack
{
    class Program
    {
        static void Main(string[] args)
        {
            byte[] key = new byte[24];
            for (int i = 0; i < key.Length; i++)
                key[i] = 0x11;

            byte[] data = new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
            byte[] computedMac = null;
            using (MACTripleDES mac = new MACTripleDESHack(key))
            {
                computedMac = mac.ComputeHash(data);
            }
        }
    }

    class MACTripleDESHack : MACTripleDES
    {
        TripleDES _desHack = new DesHack();

        static FieldInfo _cspField = typeof(MACTripleDES).GetField("des", BindingFlags.Instance | BindingFlags.NonPublic);

        public MACTripleDESHack()
            : base()
        {
            RewireDes();
        }

        public MACTripleDESHack(byte[] rgbKey)
            : base(rgbKey)
        {
            RewireDes();
        }

        private void RewireDes()
        {
            _cspField.SetValue(this, _desHack);
        }

    }

    class DesHack : TripleDES
    {
        TripleDESCryptoServiceProvider _backing = new TripleDESCryptoServiceProvider();

        static MethodInfo _newEncryptor;
        static object _encrypt;
        static object _decrypt;

        public override int BlockSize
        {
            get
            {
                return _backing.BlockSize;
            }
            set
            {
                _backing.BlockSize = value;
            }
        }

        public override int FeedbackSize
        {
            get
            {
                return _backing.FeedbackSize;
            }
            set
            {
                _backing.FeedbackSize = value;
            }
        }

        // For these two we ALSO need to avoid
        // the base class - it also checks
        // for weak keys.
        private byte[] _iv;
        public override byte[] IV
        {
            get
            {
                return _iv;
            }
            set
            {
                _iv = value;
            }
        }

        private byte[] _key;
        public override byte[] Key
        {
            get
            {
                return _key;
            }
            set
            {
                _key = value;
            }
        }

        public override int KeySize
        {
            get
            {
                return _backing.KeySize;
            }
            set
            {
                _backing.KeySize = value;
            }
        }

        public override KeySizes[] LegalBlockSizes
        {
            get
            {
                return _backing.LegalBlockSizes;
            }
        }

        public override KeySizes[] LegalKeySizes
        {
            get
            {
                return _backing.LegalKeySizes;
            }
        }

        public override CipherMode Mode
        {
            get
            {
                return _backing.Mode;
            }
            set
            {
                _backing.Mode = value;
            }
        }

        public override PaddingMode Padding
        {
            get
            {
                return _backing.Padding;
            }
            set
            {
                _backing.Padding = value;
            }
        }


        static DesHack()
        {
            _encrypt = typeof(object).Assembly.GetType("System.Security.Cryptography.CryptoAPITransformMode").GetField("Encrypt").GetValue(null);
            _decrypt = typeof(object).Assembly.GetType("System.Security.Cryptography.CryptoAPITransformMode").GetField("Decrypt").GetValue(null);
            _newEncryptor = typeof(TripleDESCryptoServiceProvider).GetMethod("_NewEncryptor", BindingFlags.NonPublic | BindingFlags.Instance);
        }

        public DesHack()
        {            
        }

        public override ICryptoTransform CreateDecryptor()
        {
            return CreateDecryptor(_key, _iv);
        }

        public override ICryptoTransform CreateEncryptor()
        {
            return CreateEncryptor(_key, _iv);
        }

        public override ICryptoTransform CreateDecryptor(byte[] rgbKey, byte[] rgbIV)
        {
            // return this._NewEncryptor(rgbKey, base.ModeValue, rgbIV, base.FeedbackSizeValue, CryptoAPITransformMode.Decrypt);
            return (ICryptoTransform) _newEncryptor.Invoke(_backing,
                new object[] { rgbKey, ModeValue, rgbIV, FeedbackSizeValue, _decrypt });
        }

        public override ICryptoTransform CreateEncryptor(byte[] rgbKey, byte[] rgbIV)
        {
            // return this._NewEncryptor(rgbKey, base.ModeValue, rgbIV, base.FeedbackSizeValue, CryptoAPITransformMode.Encrypt);
            return (ICryptoTransform) _newEncryptor.Invoke(_backing,
                new object[] { rgbKey, ModeValue, rgbIV, FeedbackSizeValue, _encrypt });
        }

        public override void GenerateIV()
        {
            _backing.GenerateIV();
        }

        public override void GenerateKey()
        {
            _backing.GenerateKey();
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
                ((IDisposable) _backing).Dispose();
            base.Dispose(disposing);
        }
    }
}
4
ответ дан 2 December 2019 в 22:05
поделиться

На форумах MSDN

есть отличное предложение об использовании отражения
1
ответ дан 2 December 2019 в 22:05
поделиться
Другие вопросы по тегам:

Похожие вопросы: