C# 如何使用3DES加密结果计算MAC值

C# 如何使用3DES加密结果计算MAC值,c#,.net,c#-4.0,C#,.net,C# 4.0,我在C.有一个项目要做。我有一个项目的要求,这部分只是整个项目的一小部分。我得到了测试数据和结果。我需要对它进行编码,以便得到正确的结果。目前我还没有得到最终结果 请不要质疑或批评这些要求,这是我所拥有的,需要整理和编码。 我被告知获取输入字符串“abc”,并为此计算SHA-1哈希。我让这部分工作,下面是代码: private string CalculateSHA1Hash(string text, Encoding characterEncoding) { byte[] buffe

我在
C.
有一个项目要做。我有一个项目的要求,这部分只是整个项目的一小部分。我得到了测试数据和结果。我需要对它进行编码,以便得到正确的结果。目前我还没有得到最终结果

请不要质疑或批评这些要求,这是我所拥有的,需要整理和编码。

我被告知获取输入字符串“abc”,并为此计算
SHA-1
哈希。我让这部分工作,下面是代码:

private string CalculateSHA1Hash(string text, Encoding characterEncoding)
{
     byte[] buffer = characterEncoding.GetBytes(text);
     SHA1CryptoServiceProvider sha1CryptoServiceProvider = new SHA1CryptoServiceProvider();
     byte[] s = sha1CryptoServiceProvider.ComputeHash(buffer);
     string hash = BitConverter.ToString(sha1CryptoServiceProvider.ComputeHash(buffer)).Replace("-", "");

     return hash;
}
我使用了
UTF8Encoding
,因为在需求文档中没有指定。我从中得到的结果是
A9993E364706816ABA3E25717850C26C9CD0D89D

然后我被告知将这个字符串分成3个字符串块,每个块16个字符,只使用第一个块。这就是我得到的:

block1: A9993E364706816A
我还得到了两把钥匙:

K1: 0123456789ABCDEF
K2: FEDCBA9876543210
块1将用作使用2个密钥的3DES加密的输入字符串

密码文本的结果必须是
6E5271A3F3F5C418
,我没有得到这个结果

下面是我的计算。有人能看看我做的是否正确,我在哪里做错了
Chris
(等等)给了我一些文章要读,但我仍然无法得到我需要的结果。已经有什么东西可以满足这一点了吗,我只是完全困惑了,还是怎么了

public string Encrypt(string message)
{
     string result = string.Empty;

     // Calculate the SHA1 hash
     UTF8Encoding characterEncoding = new UTF8Encoding();
     string sha1HashResult = CalculateSHA1Hash(message, characterEncoding);

     block1 = sha1HashResult.Substring(0, 16);

     byte[] block1ByteArray = characterEncoding.GetBytes(block1);

     string key = "0x" + accessKey1 + accessKey2 + accessKey1;
     byte[] keyByteArray = StringToByteArray(key).ToArray();

     byte[] enc = ComputeTripleDesEncryption(block1ByteArray, keyByteArray);
     result = ByteArrayToString(enc);

     return result;
}

public byte[] ComputeTripleDesEncryption(byte[] plainText, byte[] key)
{
     TripleDESCryptoServiceProvider des = new TripleDESCryptoServiceProvider();

     des.Key = key;
     des.GenerateIV();
     des.Mode = CipherMode.ECB;
     des.Padding = PaddingMode.None;

     ICryptoTransform ic = des.CreateEncryptor();

     byte[] enc = ic.TransformFinalBlock(plainText, 0, plainText.Length);

     return enc;
}

private byte[] StringToByteArray(String hex)
{
     if (hex.Substring(0, 2) == "0x")
     {
          hex = hex.Substring(2);
     }

     int NumberChars = hex.Length;
     byte[] bytes = new byte[NumberChars / 2];
     for (int i = 0; i < NumberChars; i += 2)
     {
          bytes[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16);
     }

     return bytes;
}

private string ByteArrayToString(byte[] ba)
{
     string hex = BitConverter.ToString(ba);

     return hex.Replace("-", "");
}
公共字符串加密(字符串消息)
{
字符串结果=string.Empty;
//计算SHA1散列
UTF8Encoding characterEncoding=新的UTF8Encoding();
字符串sha1HashResult=CalculateSHA1Hash(消息、字符编码);
block1=sha1HashResult.Substring(0,16);
byte[]block1ByteArray=characterEncoding.GetBytes(block1);
string key=“0x”+accessKey1+accessKey2+accessKey1;
字节[]keyByteArray=StringToByteArray(键).ToArray();
字节[]enc=计算TripledEncryption(block1ByteArray,keyByteArray);
结果=ByteArrayToString(enc);
返回结果;
}
公共字节[]计算加密(字节[]明文,字节[]密钥)
{
TripleDESCryptoServiceProvider des=新的TripleDESCryptoServiceProvider();
des.Key=Key;
des.GenerateIV();
des.Mode=CipherMode.ECB;
des.Padding=PaddingMode.None;
ICryptoTransform ic=des.CreateEncryptor();
字节[]enc=ic.TransformFinalBlock(纯文本,0,纯文本.Length);
返回enc;
}
专用字节[]StringToByteArray(字符串十六进制)
{
如果(十六进制子字符串(0,2)=“0x”)
{
十六进制=十六进制子串(2);
}
int numbercars=十六进制长度;
字节[]字节=新字节[numbercars/2];
对于(int i=0;i

我真的不知道下一步该怎么办。

你现在拥有的东西有一些问题:

  • 您指定需要使用静脉注射,但您使用的是ECB(不使用静脉注射)
  • 您正在使用GenerateIV()随机生成IV。如果不使用ECB,每次结果都会不同
  • 您只对最后一个块执行变换,而不是对整个数据执行变换
  • 有关如何在C#中使用3DE的详细信息,请参见以下代码示例:


    我猜既然你指定了静脉注射,你实际上应该使用CBC而不是ECB。试试看你会得到什么。

    @Yaur:我为IV指定了des.GenerateIV()。这还不够吗?因为你使用的是ECB模式,所以IV实际上并不重要。既然你有密钥,你有加密数据,你最好的办法就是解密它,看看输入数据应该是什么,这将帮助你找出需要如何调整哈希代码来生成它。我想我会注意到,你在第一个代码段中计算了两次哈希,而你没有使用第一个。删除以下行:
    byte[]s=sha1CryptoServiceProvider.ComputeHash(缓冲区)@polymone:谢谢你的发现,我用它来查看值。它没有在其他任何地方使用,所以不是这个导致了问题。@BrendanVogt-是的,我只是指出它是冗余代码。Yaur的回答是你目前的最佳选择。还有,你确定你要用ECB吗?这是一种非常弱的密码模式。谢谢你的建议。你建议我改用TransformBlock吗?不,按照我发布的MSDN链接中的代码示例使用流。您只需要在写入流后使用FlushFinalBlock。