I'm using the .NET 3.0 class System.Security.Cryptography.MACTripleDES
class to generate a MAC value. Unfortunately, I am working with a hardware device that uses "1111111111111111
" (as hex) as a single-length DES key. The System.Security.Cryptography
library does some sanity checking on the key and returns a Exception if you try to use a cryptographically weak key.
For example:
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);
}
throws an exception
System.Security.Cryptography.CryptographicException : Specified key is a known weak key for 'TripleDES' and cannot be used.
I know this is not a secure key. In production, the device will be flashed with a new, secure key. In the mean time, is there any way to inhibit this Exception from being thrown? Perhaps an app.config
or registry setting?
Edit: The key would actually be 101010... due to the algorithm forcing odd parity. I'm not sure if this is universal to the DES algorithm or just a requirement in the payment processing work I do.
Edit 2: Daniel's answer below has some very good information about hacking .NET. Unfortunately, I wasn't able to solve my problem using this technique, but there is still some interesting reading there.
I wouldn't really recommend it, but you should be able to modify the IL-code that checks for weak keys using Reflector and the Add-in ReflexIL
edit:
Sorry, it took a while for me to load all of it up in my Virtual Machine (running Ubuntu) and didn't want to mess with Mono.
In your assemblies pane (left one), you can now scroll up and click on "Common Language Runtime Library", the ReflexIL pane will give you an option to save it.
Important notes:
Good luck! If you need additional instructions, please feel free to use the commentbox.
edit2:
I'm confused!
I completely removed the IsWeakKey check from the set_Key function in the mscorlib assembly. I am absolutely certain that I modified the correct function, and that I did it correctly. Reflector's disassembler does no longer show the check. The funny thing is however, that Visual C# still throws the same exception.
This leads me to believe that mscorlib must somehow still be cached somewhere. However, renaming mscorlib.dll to mscorlib.dll_ leads MSVC# to crash, so it must still be dependent on the original dll.
This is quite interesting stuff, but I think I've reached the point where I have no clue what is going on, it just doesn't make any sense! See attached image. :(
edit3:
I notice in Olly, that unlike assemblies such as mscoree, mscorsec and mscorwks; mscorlib.dll isn't actually located in: c:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\
But instead, in what appears to be a non-existent location: C:\WINDOWS\assembly\NativeImages_v2.0.50727_32\mscorlib\6d667f19d687361886990f3ca0f49816\mscorlib.ni.dll
I think I am missing something here :) Will investigate this some more.
edit4:
Even after having patched out EVERYTHING in IsWeakKey, and played around with both removing and generating new native images (x.ni.dll) of mscorlib.dll using "ngen.exe", I am getting the same exception. I must be noted that even after uninstalling the native mscorlib images, it is still using mscorlib.ni.dll... Meh.
I give up. I hope someone will be able to answer what the hell is going on because I sure don't know. :)