2013-10-18 3 views
1

나는 http://support.microsoft.com/kb/307010에서 거의 복사 + 붙여 넣기 인이 두 가지 방법을 사용합니다.C# DES 파일 복호화 비 텍스트 파일 속보

파일을 암호 해독 할 때 .txt, .xml, .html 등의 텍스트 파일 형식 인 경우 파일을 열면 모든 파일을 열 수 있습니다. .exe, .jpg, .pdf 등과 같은 텍스트가 아닌 모든 유형의 파일은 해독 될 때 모두 손상됩니다. 내가 잘못하고있는 것이 있습니까? 이 방법들은 바이너리를 사용하여 파일을 암호화/해독합니까? 내가 바이너리로 만들 수있는 방법이 없다면?

도움을 주시면 대단히 감사하겠습니다.

public static void EncryptFile(string sInputFilename, 
     string sOutputFilename, 
     string sKey) 
    { 
     FileStream fsInput = new FileStream(sInputFilename, 
      FileMode.Open, 
      FileAccess.Read); 

     FileStream fsEncrypted = new FileStream(sOutputFilename, 
      FileMode.Create, 
      FileAccess.Write); 
     DESCryptoServiceProvider DES = new DESCryptoServiceProvider(); 
     DES.Key = ASCIIEncoding.ASCII.GetBytes(sKey); 
     DES.IV = ASCIIEncoding.ASCII.GetBytes(sKey); 
     ICryptoTransform desencrypt = DES.CreateEncryptor(); 
     CryptoStream cryptostream = new CryptoStream(fsEncrypted, 
      desencrypt, 
      CryptoStreamMode.Write); 

     byte[] bytearrayinput = new byte[fsInput.Length]; 
     fsInput.Read(bytearrayinput, 0, bytearrayinput.Length); 
     cryptostream.Write(bytearrayinput, 0, bytearrayinput.Length); 
     cryptostream.Close(); 
     fsInput.Close(); 
     fsEncrypted.Close(); 
    } 

    public static void DecryptFile(string sInputFilename, 
     string sOutputFilename, 
     string sKey) 
    { 
     DESCryptoServiceProvider DES = new DESCryptoServiceProvider(); 
     //A 64 bit key and IV is required for this provider. 
     //Set secret key For DES algorithm. 
     DES.Key = ASCIIEncoding.ASCII.GetBytes(sKey); 
     //Set initialization vector. 
     DES.IV = ASCIIEncoding.ASCII.GetBytes(sKey); 

     //Create a file stream to read the encrypted file back. 
     FileStream fsread = new FileStream(sInputFilename, 
      FileMode.Open, 
      FileAccess.Read); 
     //Create a DES decryptor from the DES instance. 
     ICryptoTransform desdecrypt = DES.CreateDecryptor(); 
     //Create crypto stream set to read and do a 
     //DES decryption transform on incoming bytes. 
     CryptoStream cryptostreamDecr = new CryptoStream(fsread, 
      desdecrypt, 
      CryptoStreamMode.Read); 
     //Print the contents of the decrypted file. 
     StreamWriter fsDecrypted = new StreamWriter(sOutputFilename); 
     fsDecrypted.Write(new StreamReader(cryptostreamDecr).ReadToEnd()); 
     fsDecrypted.Flush(); 
     fsDecrypted.Close(); 
     fsread.Close(); 
     cryptostreamDecr.Close(); 
    } 
+0

암호화는 암호화하는 바이트가 암호화되지 않았는지 확인합니다. –

+0

어떻게 든 여분의 바이트를 쓰고 있습니까? 아니면 너무 적습니까? –

답변

3

나는 그 기사를 쓴 사람이 흡연 무엇인지 알고 있지만하지 않습니다

DESCryptoServiceProvider desCrypto = 
    (DESCryptoServiceProvider)DESCryptoServiceProvider.Create(); 

return ASCIIEncoding.ASCII.GetString(desCrypto.Key); 

당신에게 유효한 키을받지 않습니다. 적어도 하나의 문제는 암호화하는 데 사용하는 키가 해독하는 데 사용하는 키와 다른 것이므로 바이트를 ASCII로 변환 할 수 없기 때문입니다. 당신이 문자열로 키를 치료하려면

, 당신이 아마 원하는 것은 그런 다음

string keyAsString = Convert.ToBase64String(desCrypto.Key); 

당신이 바이트로 다시 설정하고자 할 때, 대신 ASCIIEncoding.ASCII.GetBytes, 당신은 할 수 있습니다 :

byte[] key = Convert.FromBase64String(keyAsString); 

편집

너무 그 기사 더 잘못 톤이있다. 나는 그 하나를 무시하고 더 좋은 예를 찾는다.

편집

여기 내 표준 암호화의 요구에 사용할 예를 작동하는 매우 깨끗 기본 AES를합니다. 기사를 통해 주요 개선 중 일부는 다음과 같습니다

  • 핵심
  • 현재 알고리즘 (AES 256 비트 키)의 적절한 생성
  • 랜덤 IV
  • 대신 독서의
  • 버퍼 파일 액세스/쓰는 그에서 제외 using

한 덩어리의 모든 일회용 객체를 포장

  • 의 전체 파일, 그것은 같은 BAS입니다 ic idea.

    using System; 
    using System.IO; 
    using System.Security.Cryptography; 
    
    namespace ConsoleApplication12 
    { 
        class Program 
        { 
         private const int KEY_SIZE_BYTES = 32; 
         private const int IV_SIZE_BYTES = 16; 
    
         static void Main(string[] args) 
         { 
          var rand = new Random(); 
          using (var fs = File.Open(@"C:\temp\input.bin", FileMode.Create, FileAccess.Write, FileShare.None)) 
          { 
           byte[] buffer = new byte[10000]; 
           for (int i = 0; i < 100; ++i) 
           { 
            rand.NextBytes(buffer); 
            fs.Write(buffer, 0, buffer.Length); 
           } 
          } 
          string key = GenerateRandomKey(); 
          Encrypt(@"C:\temp\input.bin", @"C:\temp\encrypted.bin", key); 
          Decrypt(@"C:\temp\encrypted.bin", @"C:\temp\decyrypted.bin", key); 
         } 
    
         static string GenerateRandomKey() 
         { 
          byte[] key = new byte[KEY_SIZE_BYTES]; 
          using (var rng = RandomNumberGenerator.Create()) 
          { 
           rng.GetBytes(key); 
          } 
          return Convert.ToBase64String(key); 
         } 
    
         static void Encrypt(string inputFile, string outputFile, string key) 
         { 
          const int BUFFER_SIZE = 8192; 
          byte[] buffer = new byte[BUFFER_SIZE]; 
          byte[] keyBytes = Convert.FromBase64String(key); 
          byte[] ivBytes = new byte[IV_SIZE_BYTES]; 
          using (var rng = RandomNumberGenerator.Create()) 
          { 
           rng.GetBytes(ivBytes); 
          } 
          using (var inputStream = File.Open(inputFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) 
          { 
           using (var outputStream = File.Open(outputFile, FileMode.Create, FileAccess.Write, FileShare.None)) 
           { 
            outputStream.Write(ivBytes, 0, ivBytes.Length); 
            using (var cryptoAlgo = Aes.Create()) 
            { 
             using (var encryptor = cryptoAlgo.CreateEncryptor(keyBytes, ivBytes)) 
             { 
              using (var cryptoStream = new CryptoStream(outputStream, encryptor, CryptoStreamMode.Write)) 
              { 
               int count; 
               while ((count = inputStream.Read(buffer, 0, buffer.Length)) > 0) 
               { 
                cryptoStream.Write(buffer, 0, count); 
               } 
              } 
             } 
            } 
           } 
          } 
         } 
    
         static void Decrypt(string inputFile, string outputFile, string key) 
         { 
          const int BUFFER_SIZE = 8192; 
          byte[] buffer = new byte[BUFFER_SIZE]; 
          byte[] keyBytes = Convert.FromBase64String(key); 
          byte[] ivBytes = new byte[IV_SIZE_BYTES]; 
          using (var inputStream = File.Open(inputFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) 
          { 
           inputStream.Read(ivBytes, 0, ivBytes.Length); 
           using (var outputStream = File.Open(outputFile, FileMode.Create, FileAccess.Write, FileShare.None)) 
           { 
            using (var cryptoAlgo = Aes.Create()) 
            { 
             using (var decryptor = cryptoAlgo.CreateDecryptor(keyBytes, ivBytes)) 
             { 
              using (var cryptoStream = new CryptoStream(inputStream, decryptor, CryptoStreamMode.Read)) 
              { 
               int count; 
               while ((count = cryptoStream.Read(buffer, 0, buffer.Length)) > 0) 
               { 
                outputStream.Write(buffer, 0, count); 
               } 
              } 
             } 
            } 
           } 
          } 
         } 
        } 
    } 
    

    IV가 무작위이기 때문에 기술에 약간의 차이가 있음을 알 수 있습니다. 파일을 암호화 할 때는 먼저 암호화 된 파일에 IV를 작성합니다 (비밀이 아니므로 직접 작성하십시오). 파일을 해독 할 때 IV를 검색하기 위해 처음 몇 바이트를 읽은 다음 나머지 파일에는 실제 암호화 된 데이터가 들어 있습니다. 무작위 IV의 목적은 동일한 평문 파일이 실행될 때마다 다른 암호화 된 파일로 암호화되기 때문입니다.

    여기서 Main 방법은 임의의 키를 사용한 암호화를 보여줍니다.암호를 사용하려면 좀 더 많은 작업이 필요하지만 PBKDF2를 구현할 수있는 코드는 12 개 정도가 될 수 있습니다.

  • +0

    정보를 제공해 주셔서 감사합니다. 나는 더 나은 모범을 찾으려고 노력할 것이다. –

    +0

    @LandonHammond 제 대답은 전체 AES 예제로 편집되었습니다. 이것을 시작점으로 사용하고 필요에 따라 조정할 수 있습니다. –

    +1

    원래 질문 PBKDF2의 노트 OP가 .NET에 내장되어있는 것처럼 [Rfc2898DeriveBytes] (http://msdn.microsoft.com/en-us/library/system.security.cryptography.rfc2898derivebytes.aspx) –