DES 解密仅在密钥为 0 时有效
DES decryption only working when the key is 0s
我遇到了一个奇怪的行为。每当我将 DES 密钥设置为 0 时,解密都会起作用,但如果我将密钥设置为其他任何内容,则解密 returns 一个不可读的字符串:
主要方法:
static void Main(string[] args)
{
//Decryption works!
byte[] key0 = new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
//Decryption doesn't work!
byte[] key1 = new byte[] { 0x00, 0xFF, 0xFF, 0xAF, 0x12, 0x14, 0x15, 0xEC };
SimpleDES des = new SimpleDES(key1);
byte[] data = Encoding.ASCII.GetBytes("12345678");
byte[] encrypted = des.Encrypt(data);
byte[] decrypted = des.Decrypt(encrypted);
string decryptedString = Encoding.ASCII.GetString(decrypted);
//Only shows original plaintext if key0 is used.
Console.WriteLine("Decrypted string: {0}", decryptedString);
Console.ReadKey();
}
简单 DES class:
public class SimpleDES
{
private readonly byte[] IV = new byte[8] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
private byte[] mKey;
private DESCryptoServiceProvider des;
public SimpleDES(byte[] aKey)
{
if (aKey.Length != 8)
throw new Exception("Key size must be 8 bytes");
mKey = aKey;
des = new DESCryptoServiceProvider();
des.BlockSize = 64;
des.KeySize = 64;
des.Padding = PaddingMode.None;
}
public byte[] Encrypt(byte[] data)
{
if (data.Length != 8)
throw new Exception("Data size must be 8 bytes");
ICryptoTransform encryptor = des.CreateWeakEncryptor(mKey, IV);
return encryptor.TransformFinalBlock(data, 0, data.Length);
}
public byte[] Decrypt(byte[] data)
{
if (data.Length != 8)
throw new Exception("Data size must be 8 bytes");
ICryptoTransform decryptor = des.CreateWeakDecryptor(mKey, IV);
return decryptor.TransformFinalBlock(data, 0, data.Length);
}
}
DESCryptoExtensions class:
public static class DESCryptoExtensions
{
public static ICryptoTransform CreateWeakEncryptor(this DESCryptoServiceProvider cryptoProvider, byte[] key, byte[] iv)
{
// reflective way of doing what CreateEncryptor() does, bypassing the check for weak keys
MethodInfo mi = cryptoProvider.GetType().GetMethod("_NewEncryptor", BindingFlags.NonPublic | BindingFlags.Instance);
object[] Par = { key, cryptoProvider.Mode, iv, cryptoProvider.FeedbackSize, 0 };
ICryptoTransform trans = mi.Invoke(cryptoProvider, Par) as ICryptoTransform;
return trans;
}
public static ICryptoTransform CreateWeakEncryptor(this DESCryptoServiceProvider cryptoProvider)
{
return CreateWeakEncryptor(cryptoProvider, cryptoProvider.Key, cryptoProvider.IV);
}
public static ICryptoTransform CreateWeakDecryptor(this DESCryptoServiceProvider cryptoProvider, byte[] key, byte[] iv)
{
return CreateWeakEncryptor(cryptoProvider, key, iv);
}
public static ICryptoTransform CreateWeakDecryptor(this DESCryptoServiceProvider cryptoProvider)
{
return CreateWeakDecryptor(cryptoProvider, cryptoProvider.Key, cryptoProvider.IV);
}
}
key0 输出:
key1 输出:
_NewEncryptor
(最后一个)中有一个CryptoAPITransformMode
参数你忘记了。你把它 "fixed" 放在 0,但它可以是 0 或 1(Encrypt
或 Decrypt
)。它是内部的,但最后传递一个 int
就可以了。
public static class DESCryptoExtensions
{
// Mode = 0 encrypt, 1 decrypt
public static ICryptoTransform CreateWeakEncryptor(this DESCryptoServiceProvider cryptoProvider, byte[] key, byte[] iv, int mode = 0)
{
// reflective way of doing what CreateEncryptor() does, bypassing the check for weak keys
MethodInfo mi = cryptoProvider.GetType().GetMethod("_NewEncryptor", BindingFlags.NonPublic | BindingFlags.Instance);
object[] Par = { key, cryptoProvider.Mode, iv, cryptoProvider.FeedbackSize, mode };
ICryptoTransform trans = mi.Invoke(cryptoProvider, Par) as ICryptoTransform;
return trans;
}
public static ICryptoTransform CreateWeakEncryptor(this DESCryptoServiceProvider cryptoProvider)
{
return CreateWeakEncryptor(cryptoProvider, cryptoProvider.Key, cryptoProvider.IV);
}
public static ICryptoTransform CreateWeakDecryptor(this DESCryptoServiceProvider cryptoProvider, byte[] key, byte[] iv)
{
return CreateWeakEncryptor(cryptoProvider, key, iv, 1);
}
public static ICryptoTransform CreateWeakDecryptor(this DESCryptoServiceProvider cryptoProvider)
{
return CreateWeakDecryptor(cryptoProvider, cryptoProvider.Key, cryptoProvider.IV);
}
}
我遇到了一个奇怪的行为。每当我将 DES 密钥设置为 0 时,解密都会起作用,但如果我将密钥设置为其他任何内容,则解密 returns 一个不可读的字符串:
主要方法:
static void Main(string[] args)
{
//Decryption works!
byte[] key0 = new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
//Decryption doesn't work!
byte[] key1 = new byte[] { 0x00, 0xFF, 0xFF, 0xAF, 0x12, 0x14, 0x15, 0xEC };
SimpleDES des = new SimpleDES(key1);
byte[] data = Encoding.ASCII.GetBytes("12345678");
byte[] encrypted = des.Encrypt(data);
byte[] decrypted = des.Decrypt(encrypted);
string decryptedString = Encoding.ASCII.GetString(decrypted);
//Only shows original plaintext if key0 is used.
Console.WriteLine("Decrypted string: {0}", decryptedString);
Console.ReadKey();
}
简单 DES class:
public class SimpleDES
{
private readonly byte[] IV = new byte[8] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
private byte[] mKey;
private DESCryptoServiceProvider des;
public SimpleDES(byte[] aKey)
{
if (aKey.Length != 8)
throw new Exception("Key size must be 8 bytes");
mKey = aKey;
des = new DESCryptoServiceProvider();
des.BlockSize = 64;
des.KeySize = 64;
des.Padding = PaddingMode.None;
}
public byte[] Encrypt(byte[] data)
{
if (data.Length != 8)
throw new Exception("Data size must be 8 bytes");
ICryptoTransform encryptor = des.CreateWeakEncryptor(mKey, IV);
return encryptor.TransformFinalBlock(data, 0, data.Length);
}
public byte[] Decrypt(byte[] data)
{
if (data.Length != 8)
throw new Exception("Data size must be 8 bytes");
ICryptoTransform decryptor = des.CreateWeakDecryptor(mKey, IV);
return decryptor.TransformFinalBlock(data, 0, data.Length);
}
}
DESCryptoExtensions class:
public static class DESCryptoExtensions
{
public static ICryptoTransform CreateWeakEncryptor(this DESCryptoServiceProvider cryptoProvider, byte[] key, byte[] iv)
{
// reflective way of doing what CreateEncryptor() does, bypassing the check for weak keys
MethodInfo mi = cryptoProvider.GetType().GetMethod("_NewEncryptor", BindingFlags.NonPublic | BindingFlags.Instance);
object[] Par = { key, cryptoProvider.Mode, iv, cryptoProvider.FeedbackSize, 0 };
ICryptoTransform trans = mi.Invoke(cryptoProvider, Par) as ICryptoTransform;
return trans;
}
public static ICryptoTransform CreateWeakEncryptor(this DESCryptoServiceProvider cryptoProvider)
{
return CreateWeakEncryptor(cryptoProvider, cryptoProvider.Key, cryptoProvider.IV);
}
public static ICryptoTransform CreateWeakDecryptor(this DESCryptoServiceProvider cryptoProvider, byte[] key, byte[] iv)
{
return CreateWeakEncryptor(cryptoProvider, key, iv);
}
public static ICryptoTransform CreateWeakDecryptor(this DESCryptoServiceProvider cryptoProvider)
{
return CreateWeakDecryptor(cryptoProvider, cryptoProvider.Key, cryptoProvider.IV);
}
}
key0 输出:
_NewEncryptor
(最后一个)中有一个CryptoAPITransformMode
参数你忘记了。你把它 "fixed" 放在 0,但它可以是 0 或 1(Encrypt
或 Decrypt
)。它是内部的,但最后传递一个 int
就可以了。
public static class DESCryptoExtensions
{
// Mode = 0 encrypt, 1 decrypt
public static ICryptoTransform CreateWeakEncryptor(this DESCryptoServiceProvider cryptoProvider, byte[] key, byte[] iv, int mode = 0)
{
// reflective way of doing what CreateEncryptor() does, bypassing the check for weak keys
MethodInfo mi = cryptoProvider.GetType().GetMethod("_NewEncryptor", BindingFlags.NonPublic | BindingFlags.Instance);
object[] Par = { key, cryptoProvider.Mode, iv, cryptoProvider.FeedbackSize, mode };
ICryptoTransform trans = mi.Invoke(cryptoProvider, Par) as ICryptoTransform;
return trans;
}
public static ICryptoTransform CreateWeakEncryptor(this DESCryptoServiceProvider cryptoProvider)
{
return CreateWeakEncryptor(cryptoProvider, cryptoProvider.Key, cryptoProvider.IV);
}
public static ICryptoTransform CreateWeakDecryptor(this DESCryptoServiceProvider cryptoProvider, byte[] key, byte[] iv)
{
return CreateWeakEncryptor(cryptoProvider, key, iv, 1);
}
public static ICryptoTransform CreateWeakDecryptor(this DESCryptoServiceProvider cryptoProvider)
{
return CreateWeakDecryptor(cryptoProvider, cryptoProvider.Key, cryptoProvider.IV);
}
}