2011-10-05 93 views
0

我有一個項目需要做的工作要做在C#。我對項目有要求,這部分只是整個項目的一小部分。我獲得了測試數據和結果。我需要編寫代碼才能獲得正確的結果。目前我還沒有得到最終結果。如何使用3DES加密結果計算MAC值

請不要質疑或批評要求,這是我有,需要整理和編碼。

我被告知需要輸入字符串​​並計算這個散列值爲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個字符,並且只使用第1個塊。這是我的了:

block1: A9993E364706816A 

我也給予2個鍵:

K1:ABCDEF 
K2: FEDCBA

塊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("-", ""); 
} 

我真的不知道該做些什麼。

+0

@Yaur:我爲IV指定了des.GenerateIV()。這不夠嗎? –

+2

因爲您正在使用ECB模式,IV實際上並不重要。既然你有密鑰,並且你有加密的數據,你最好的辦法就是解密它,看看輸入的數據應該是什麼,這將幫助你找出你需要調整你的哈希代碼來生成它。 – Yaur

+0

只是想我會注意到你在計算你的第一個代碼片段中的哈希兩次,而你沒有使用第一個。刪除以下行:'byte [] s = sha1CryptoServiceProvider.ComputeHash(buffer);' – Polynomial

回答

1

有幾件事情錯了,你有什麼權利現在:

  1. 你指定你需要使用一個IV,但你使用ECB(不使用IV)
  2. 您正在使用GenerateIV()隨機生成IV。如果您沒有使用ECB,這會導致結果每次都會有所不同。
  3. 您只對最終塊執行轉換,而不是整個數據。

請看下面的代碼樣本如何在C#中使用3DES一個體面的想法:
http://msdn.microsoft.com/en-us/library/system.security.cryptography.tripledescryptoserviceprovider.aspx

我猜想,因爲你指定IV,你實際上的意思是使用CBC而不是ECB。試試看看你得到了什麼。

+0

感謝您的所有建議。你建議我使用TransformBlock嗎? –

+0

不,根據我發佈的MSDN鏈接中的代碼示例使用流。在寫入流之後,只需要使用FlushFinalBlock。 – Polynomial