2014-02-25 179 views
2

我在與生成KCV在C#.NET計算KCV與DES密鑰

在參考this答案DES密鑰出了問題,KCV DES密鑰「ABCDEF」「 D5D44F「(因爲只考慮前3個字節),它是由包含64位」0「的塊生成的。

http://www.emvlab.org/keyshares/?combined=ABCDEF&combined_kcv=&one=&one_kcv=&two=&two_kcv=&three=&three_kcv=&numcomp=three&parity=ignore&action=Split

所以我確信我應該得到D5D44F的KCV:要確認這是正確的價值,我也是用這個工具,這給了我同樣的結果進行檢查。

現在,當我嘗試在C#.NET中實現它時,我完全得到了一個不同的值。我結束了「7217BF」

這裏是我的代碼:

using System; 
using System.IO; 
using System.Security.Cryptography; 
using System.Text; 

namespace ConsoleApplication1 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      Console.WriteLine(GetKCVDES()); 
      Console.ReadLine(); 
     } 

     public static string GetKCVDES() 
     { 
      byte[] k = new byte[] { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF }; 
      byte[] i = new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 
      byte[] d = new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 

      DES des = new DESCryptoServiceProvider(); 
      MemoryStream memoryStream = new MemoryStream(); 
      CryptoStream cryptoStream = new CryptoStream(memoryStream, des.CreateEncryptor(k, i), CryptoStreamMode.Write); 
      StreamWriter writer = new StreamWriter(cryptoStream); 

      writer.Write(d); 
      writer.Flush(); 
      cryptoStream.FlushFinalBlock(); 
      writer.Flush(); 
      return ByteArrayToString(memoryStream.GetBuffer()).Remove(6); 
     } 

     public static string ByteArrayToString(byte[] ba) 
     { 
      StringBuilder hex = new StringBuilder(ba.Length * 2); 
      foreach (byte b in ba) 
       hex.AppendFormat("{0:x2}", b); 
      return hex.ToString().ToUpper(); 
     } 
    } 
} 

的ByteArrayToString功能只是字節數組到一個十六進制字符串轉換。在傳遞之前,我還檢查了Byte數組,以確保ByteArrayToString方法未提供不同的輸出。

我也試着明確強制DES CSP的ECB和CBC模式,但是我得到了相同的結果。

有沒有我用DES CSP錯誤地實現的東西?

+0

你有沒有試過用'TransformBlock'您已經創建了一個ECB模式下使用'CreateEncryptor'加密器實例後?這裏不需要所有這些流。 –

+0

謝謝owlstead,我似乎已經從你的建議中解決了它。我還沒有實現TransformBlock函數,但重構刪除其中一個流似乎已經修復它。現在發佈答案。 – quinnoth

回答

0

感謝owlstead的評論,我從函數中刪除了StreamWriter(開始擺脫流),它現在給出了預期的輸出。

我還沒有完全理解這些Stream對象是如何工作的,所以我不知道它現在的工作原理的真正原因,但是通過對GetKCVDES函數的更新,我得到了我想要的KCV得到(我還簡化了它更多地與使用語句位):

public static string GetKCVDES() 
{ 
    byte[] key = new byte[] { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF }; 
    byte[] iv = new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 
    byte[] data = new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 

    DES des = new DESCryptoServiceProvider(); 

    using (MemoryStream memoryStream = new MemoryStream()) 
    { 
     using (CryptoStream cryptoStream = new CryptoStream(memoryStream, des.CreateEncryptor(key, iv), CryptoStreamMode.Write)) 
     { 
      cryptoStream.Write(data, 0, data.Length); 
      cryptoStream.FlushFinalBlock(); 
      return ByteArrayToString(memoryStream.ToArray()).Remove(6); 
     } 
    } 
}