2014-02-25 11 views
2
내가 this 대답을 참조에서

C# .NET에서 DES의 키에 대한 KCV를 생성에 문제가있어

의 DES 키 "abcdef가"에 대한 KCV는 "입니다 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에서이를 구현하려고하면 전적으로 다른 값을 얻게됩니다.

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 기능은 단지 진수 문자열로 바이트 배열로 변환 : 나는 "7217BF"

여기 내 코드의와 끝까지. 또한 ByteArrayToString 메서드가 다른 출력을 제공하지 않도록 전달하기 전에 Byte 배열을 검사했습니다.

나는 또한 명시 적으로 DES CSP에 대해 ECB와 CBC 모드를 모두 강요했지만 어느 쪽에서도 같은 결과를 얻었습니다.

DES CSP에서 잘못 구현 한 것이 있습니까?

+0

당신이 ECB 모드에서'CreateEncryptor'를 사용하여 암호 화기 인스턴스를 생성 한 후'TransformBlock'를 사용하려고 있나요? 이 모든 흐름이 필요 없습니다. –

+0

감사합니다. owlstead, 귀하의 충고에 따라 해결 한 것 같습니다. 아직 TransformBlock 함수를 구현하지 않았지만 스트림 중 하나를 제거하기위한 리팩터링을 통해 수정 된 것으로 보입니다. 지금 답변 게시. – quinnoth

답변

0

owlstead의 의견 덕분에 함수에서 스트림 제거를 시작하기 위해 StreamWriter를 제거 했으므로 예상되는 출력을 제공합니다.

이 스트림 객체의 작동 방식을 아직 완전히 이해하지 못해서 현재 작동하는 실제 이유를 모르지만 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); 
     } 
    } 
}