Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/319.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 三元组:指定的密钥是';三倍体';不能使用_C#_.net_Cryptography_Cryptographicexception - Fatal编程技术网

C# 三元组:指定的密钥是';三倍体';不能使用

C# 三元组:指定的密钥是';三倍体';不能使用,c#,.net,cryptography,cryptographicexception,C#,.net,Cryptography,Cryptographicexception,我正在使用.NET3.0类System.Security.Cryptography.MACTripleDES类生成MAC值。不幸的是,我使用的硬件设备使用“1111111111”(十六进制)作为单个长度的DES键。System.Security.Cryptography库对密钥执行一些健全性检查,如果尝试使用加密弱密钥,则返回异常 例如: byte[] key = new byte[24]; for (int i = 0; i < key.Length; i++) key[i] = 0

我正在使用.NET3.0类
System.Security.Cryptography.MACTripleDES
类生成MAC值。不幸的是,我使用的硬件设备使用“
1111111111
”(十六进制)作为单个长度的DES键。
System.Security.Cryptography
库对密钥执行一些健全性检查,如果尝试使用加密弱密钥,则返回异常

例如:

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 MACTripleDES(key))
{
  computedMac = mac.ComputeHash(data);
}
我知道这不是一把安全的钥匙。在生产过程中,设备将使用新的安全密钥进行闪存。同时,是否有任何方法阻止抛出此异常?可能是
app.config
或注册表设置

编辑:键实际上是101010。。。由于算法强制奇偶校验。我不确定这是DES算法的通用性,还是我所做的支付处理工作中的一个要求


编辑2:丹尼尔在下面的回答中提供了一些关于黑客攻击.NET的非常好的信息。不幸的是,我无法使用此技术解决我的问题,但仍然有一些有趣的阅读。

不幸的是,该行为无法被覆盖。

我不推荐使用此技术,但您应该能够使用和外接程序修改检查弱密钥的IL代码

编辑:

对不起,我花了一段时间才把它全部加载到我的虚拟机(运行Ubuntu)中,我不想弄乱Mono

  • 安装Reflecil加载项:查看->加载项->添加
  • 打开ReflexIL:Tools->ReflexIL v0.9
  • 查找IsWeakKey()函数。(您可以使用搜索:F3)
  • 将出现两个函数,双击System.Security.Cryptography.TripleDES中的函数
  • 雷科菲尔也应该来。在“说明”选项卡中,向下滚动至第29行(偏移量63)
  • 将ldc.i4.1更改为ldc.i4.0,这意味着函数将始终返回false
在程序集窗格(左一)中,您现在可以向上滚动并单击“公共语言运行时库”,ReflexIL窗格将为您提供保存它的选项

重要提示:

  • 首先备份您的原始程序集!(mscorlib.dll)
  • mscorlib.dll是一个已签名的程序集,您需要reflecil的.NET SDK(sn.exe工具)使其跳过验证。我刚刚亲自检查过,您应该已经安装了Visual C。当要求注册时,只需单击“注册以跳过验证(在此计算机上)”
  • 我不认为我必须告诉您只在您的开发机器上使用这个:)
祝你好运!如果您需要其他说明,请随时使用评论框

编辑2:

我糊涂了

我从mscorlib程序集中的set_Key函数中完全删除了IsWeakKey检查。我绝对肯定我修改了正确的函数,并且我做得正确。反射器的拆卸器不再显示检查。然而有趣的是,VisualC仍然抛出相同的异常

这让我相信,mscorlib必须以某种方式仍被缓存在某个地方。但是,将mscorlib.dll重命名为mscorlib.dll会导致MSVC崩溃,因此它必须仍然依赖于原始dll

这是很有趣的事情,但我想我已经到了不知道发生了什么的地步,这根本没有任何意义!见附图:(

编辑3:

我在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

我想我在这里遗漏了一些东西:)我将进一步调查这一点

编辑4:

即使在修补了IsWeakKey中的所有内容,并使用“ngen.exe”删除和生成mscorlib.dll的新本机映像(x.ni.dll)之后,我也遇到了同样的异常。我必须注意,即使在卸载本机mscorlib映像之后,它仍然在使用mscorlib.ni.dll。。。嗯


我放弃了。我希望有人能回答到底发生了什么事,因为我确实不知道。:)

我不是安全专家,但是用另一个值对您的密钥进行异或不足以满足安全检查吗?您可以对调试版本(使用适当的IFDEF)执行此操作,以便在密钥足够强大的版本或生产版本中执行适当的检查并删除它。

不必使用重复DES密钥的MACTripleDES来伪造单个DES CBC-MAC,您可以自己在其上实现CBC-MAC

不是一个弱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;
    }

我知道你需要做什么了。幸运的是,有一种方法可以创建ICryptoTranforms,它不检查弱键。您还需要注意基类,因为它还执行健全性检查。Via reflection只需调用_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);
        }
    }
}
使用系统;
运用系统反思;
使用System.Security.Cryptography;
使用System.IO;
名称空间删除
{
班级计划
{
静态void Main(字符串[]参数)
{
字节[]键=新字节[24];
for(int i=0;iusing 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);
        }
    }
}
private void MakeSecureKey(byte[] key)
{
    while(TripleDES.IsWeakKey(key))
    {
        var sha = SHA256Managed.Create().ComputeHash(key);
        Array.Copy(sha,key,key.Length);
    }
}