# 探讨NET Core数据进行3DES加密或解密弱密钥问题

## 3DES加密或解密弱密钥

public static string DesEncrypt(string input, string key)
{
byte[] inputArray = Encoding.UTF8.GetBytes(input);
var tripleDES = TripleDES.Create();
var byteKey = Encoding.UTF8.GetBytes(key);
byte[] allKey = new byte[24];
Buffer.BlockCopy(byteKey, 0, allKey, 0, 16);
Buffer.BlockCopy(byteKey, 0, allKey, 16, 8);
tripleDES.Key = allKey;
tripleDES.Mode = CipherMode.ECB;
ICryptoTransform cTransform = tripleDES.CreateEncryptor();
byte[] resultArray = cTransform.TransformFinalBlock(inputArray, 0, inputArray.Length);
return Convert.ToBase64String(resultArray, 0, resultArray.Length);
}

public static string DesDecrypt(string input, string key)
{
byte[] inputArray = Convert.FromBase64String(input);
var tripleDES = TripleDES.Create();
var byteKey = Encoding.UTF8.GetBytes(key);
byte[] allKey = new byte[24];
Buffer.BlockCopy(byteKey, 0, allKey, 0, 16);
Buffer.BlockCopy(byteKey, 0, allKey, 16, 8);
tripleDES.Key = byteKey;
tripleDES.Mode = CipherMode.ECB;
ICryptoTransform cTransform = tripleDES.CreateDecryptor();
byte[] resultArray = cTransform.TransformFinalBlock(inputArray, 0, inputArray.Length);
return Encoding.UTF8.GetString(resultArray);
}

var desEncryptData = DesEncrypt("Jeffcky", "1111111111111111");

static IBufferedCipher CreateCipher(bool forEncryption, string key,
{
var algorithmName = cipMode;
if (cipMode.IndexOf('/') >= 0)
{
algorithmName = cipMode.Substring(0, cipMode.IndexOf('/'));
}

var cipher = CipherUtilities.GetCipher(cipMode);

var keyBytes = Encoding.UTF8.GetBytes(key);

var keyParameter = ParameterUtilities.CreateKeyParameter(algorithmName, keyBytes);

cipher.Init(forEncryption, keyParameter);

return cipher;
}

static string EncryptData(string input, string key)
{
var inCipher = CreateCipher(true, key);

var inputArray = Encoding.UTF8.GetBytes(input);

byte[] cipherData = inCipher.DoFinal(inputArray);

return Convert.ToBase64String(cipherData);
}

static string DecryptData(string input, string key)
{
var inputArrary = Convert.FromBase64String(input);

var outCipher = CreateCipher(false, key);

var encryptedDataStream = new MemoryStream(inputArrary, false);

var dataStream = new MemoryStream();

var outCipherStream = new CipherStream(dataStream, null, outCipher);

int ch;
while ((ch = encryptedDataStream.ReadByte()) >= 0)
{
outCipherStream.WriteByte((byte)ch);
}

outCipherStream.Close();
encryptedDataStream.Close();

var dataBytes = dataStream.ToArray();

return Encoding.UTF8.GetString(dataBytes);
}

var data = EncryptData("Jeffcky", "1111111111111111");

var decryptData = DecryptData(data, "1111111111111111");

public const int DesKeyLength = 8;

private const int N_DES_WEAK_KEYS = 16;

//基于Schneier pp281的弱和半弱键表
private static readonly byte[] DES_weak_keys =
{
/* 弱键 */
(byte)0x01,(byte)0x01,(byte)0x01,(byte)0x01, (byte)0x01,(byte)0x01,(byte)0x01,(byte)0x01,
(byte)0x1f,(byte)0x1f,(byte)0x1f,(byte)0x1f, (byte)0x0e,(byte)0x0e,(byte)0x0e,(byte)0x0e,
(byte)0xe0,(byte)0xe0,(byte)0xe0,(byte)0xe0, (byte)0xf1,(byte)0xf1,(byte)0xf1,(byte)0xf1,
(byte)0xfe,(byte)0xfe,(byte)0xfe,(byte)0xfe, (byte)0xfe,(byte)0xfe,(byte)0xfe,(byte)0xfe,

/* 半弱键 */
(byte)0x01,(byte)0xfe,(byte)0x01,(byte)0xfe, (byte)0x01,(byte)0xfe,(byte)0x01,(byte)0xfe,
(byte)0x1f,(byte)0xe0,(byte)0x1f,(byte)0xe0, (byte)0x0e,(byte)0xf1,(byte)0x0e,(byte)0xf1,
(byte)0x01,(byte)0xe0,(byte)0x01,(byte)0xe0, (byte)0x01,(byte)0xf1,(byte)0x01,(byte)0xf1,
(byte)0x1f,(byte)0xfe,(byte)0x1f,(byte)0xfe, (byte)0x0e,(byte)0xfe,(byte)0x0e,(byte)0xfe,
(byte)0x01,(byte)0x1f,(byte)0x01,(byte)0x1f, (byte)0x01,(byte)0x0e,(byte)0x01,(byte)0x0e,
(byte)0xe0,(byte)0xfe,(byte)0xe0,(byte)0xfe, (byte)0xf1,(byte)0xfe,(byte)0xf1,(byte)0xfe,
(byte)0xfe,(byte)0x01,(byte)0xfe,(byte)0x01, (byte)0xfe,(byte)0x01,(byte)0xfe,(byte)0x01,
(byte)0xe0,(byte)0x1f,(byte)0xe0,(byte)0x1f, (byte)0xf1,(byte)0x0e,(byte)0xf1,(byte)0x0e,
(byte)0xe0,(byte)0x01,(byte)0xe0,(byte)0x01, (byte)0xf1,(byte)0x01,(byte)0xf1,(byte)0x01,
(byte)0xfe,(byte)0x1f,(byte)0xfe,(byte)0x1f, (byte)0xfe,(byte)0x0e,(byte)0xfe,(byte)0x0e,
(byte)0x1f,(byte)0x01,(byte)0x1f,(byte)0x01, (byte)0x0e,(byte)0x01,(byte)0x0e,(byte)0x01,
(byte)0xfe,(byte)0xe0,(byte)0xfe,(byte)0xe0, (byte)0xfe,(byte)0xf1,(byte)0xfe,(byte)0xf1
};

public static bool IsWeakKey(byte[]    key, int offset)
{
if (key.Length - offset < DesKeyLength)
throw new ArgumentException("key material too short.");

//nextkey:
for (int i = 0; i < N_DES_WEAK_KEYS; i++)
{
bool unmatch = false;
for (int j = 0; j < DesKeyLength; j++)
{
if (key[j + offset] != DES_weak_keys[i * DesKeyLength + j])
{
//continue nextkey;
unmatch = true;
break;
}
}

if (!unmatch)
{
return true;
}
}

return false;
}

## 总结

posted @ 2020-07-04 13:52  Jeffcky  阅读(763)  评论(0编辑  收藏  举报