Автор учебного пособия использует пакет data.table
. Как вы можете прочитать здесь , использование with = F
иногда используется для получения одного столбца. Убедитесь, что вы загрузили и установили data.table
и другие пакеты, чтобы следовать руководству. Также убедитесь, что ваш набор данных является объектом data.table.
Вместо использования 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;
}
Я бы не рекомендовал это, но вы должны иметь возможность изменять IL-код, который проверяет слабые ключи, используя Reflector и надстройка ReflexIL
править:
Извините, мне потребовалось некоторое время, чтобы загрузить все это на мою виртуальную машину (работающую под управлением Ubuntu), и я не хотел связываться с Mono.
На панели сборок (левая) теперь вы можете прокрутить вверх и щелкнуть «Common Language Runtime Library», панель ReflexIL даст вам возможность сохранить ее.
Важные примечания:
Удачи! Если вам нужны дополнительные инструкции, пожалуйста, используйте поле для комментариев.
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.
Я сдаюсь. Я надеюсь, что кто-нибудь сможет ответить, что, черт возьми, происходит, потому что я точно не знаю. :)
Я не эксперт по безопасности, но не будет XOR вашего ключа с другим значением будет достаточно для проверки работоспособности ? Вы могли бы сделать это для своей отладочной версии (с надлежащим IFDEF), чтобы вы могли выполнить правильную проверку и удалить ее для своей версии или рабочей версии, где ключ будет достаточно сильным.
Я выяснил, что вам нужно сделать. К счастью, есть метод, который создает 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);
}
}
}
На форумах MSDN
есть отличное предложение об использовании отражения