C#中的简单DES ECB加密和解密



我正在尝试做一个练习,其中包括用给定的共享密钥解密给定的加密会话密钥。我已经解密了会话密钥,并在屏幕上打印了字节数组。(当我运行程序时,会打印出相同的结果)。

然后,为了检查我的工作,我试图再次加密解密的会话密钥(显然是使用相同的共享密钥),但结果一直不同,应该在什么时候给我原始加密的会话密钥。

我不明白是我的错。。。。

感谢

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Cryptography;
using System.IO;
namespace Crypto
{
public class Program
{
static void Main(string[] args)
{
//Shared Master Key
byte[] mkByteArray = { 0x12, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x23 };
//Encrypted Session Key
byte[] eskByteArray = { 0x4a, 0x4d, 0xe6, 0x87, 0x82, 0x47, 0xd3, 0x7b };
PrintByteArray(eskByteArray);
DES des = new DESCryptoServiceProvider();
des.Mode = CipherMode.ECB;
des.Padding = PaddingMode.None;
des.Key = mkByteArray;
ICryptoTransform ct1 = des.CreateDecryptor();
byte[] resultArray1 = ct1.TransformFinalBlock(eskByteArray, 0, eskByteArray.Length);
des.Clear();
PrintByteArray(resultArray1);
ICryptoTransform ct2 = des.CreateEncryptor();
byte[] resultArray2 = ct2.TransformFinalBlock(resultArray1, 0, resultArray1.Length);
des.Clear();
PrintByteArray(resultArray2);
}
//-----Method to print the byte array on screen-----
public static void PrintByteArray(byte[] bytes)
{
var sb = new StringBuilder("new byte[] { ");
foreach (var b in bytes)
{
sb.Append(b + ", ");
}
sb.Append("}");
Console.WriteLine(sb.ToString());
}
}
}

我发现了您的问题,但现在我正在检查为什么会出现这种问题。

在加密和解密之间调用des.Clear();,如果不这样做,则输入和输出是相同的。


来自Msdn:

调用时,Clear方法会用零覆盖对象内的所有敏感数据

因此,DES对象中的主密钥被设置为零,这就是为什么输出不同的原因。

这是因为初始化向量。这种行为是故意的。您不希望加密算法对相同的输入产生完全相同的输出。这种算法容易受到纯文本攻击,攻击者可以从输入和产生的输出中推断出加密密钥。

这种情况发生在行

ICryptoTransform ct2 = des.CreateEncryptor();

根据msdn

如果当前IV属性为空,GenerateIV方法被调用来创建一个新的随机IV.

要解决此问题,您需要为加密机设置IV。然后,您将IV与加密的字节一起存储,并使用它进行解密。IV、 简单地说,是一些初始的随机噪声,它允许加密算法产生不同的输入。作为一种良好的做法,这种噪声对于每个加密调用都必须不同。

显然,DES是一个非常弱的算法,你至少需要使用3DES。但即使是3DES也只用于遗留应用程序。现代应用程序使用AES。

最新更新