2009-10-27 5 views
2

C#에서 RC2CryptoServiceProvider을 사용하여 암호화/암호 해독 방법을 작성했으며 어떤 이유로 최종 해독기에서 최종 몇 바이트를 해독 할 수 없습니다. 파일이 잘린 것처럼 보입니다. 내 암호화 방법과 같이 보인다 :파일의 암호 해독 ~ 끝 문자가 ~ 10 자임

public static byte[] EncryptString(byte[] input, string password) 
    { 
     PasswordDeriveBytes pderiver = new PasswordDeriveBytes(password, null); 
     byte[] ivZeros = new byte[8]; 
     byte[] pbeKey = pderiver.CryptDeriveKey("RC2", "MD5", 128, ivZeros); 

     RC2CryptoServiceProvider RC2 = new RC2CryptoServiceProvider(); 

     byte[] IV = new byte[8]; 
     ICryptoTransform encryptor = RC2.CreateEncryptor(pbeKey, IV); 

     MemoryStream msEncrypt = new MemoryStream(); 
     CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write); 
     csEncrypt.Write(input, 0, input.Length); 
     csEncrypt.FlushFinalBlock(); 

     return msEncrypt.ToArray(); 
    } 

내 암호 해독 보이지만 같은 :

public static byte[] DecryptString(byte[] input, string password, int originalSize) 
    { 
     PasswordDeriveBytes pderiver = new PasswordDeriveBytes(password, null); 
     byte[] ivZeros = new byte[8]; 
     byte[] pbeKey = pderiver.CryptDeriveKey("RC2", "MD5", 128, ivZeros); 

     RC2CryptoServiceProvider RC2 = new RC2CryptoServiceProvider(); 

     byte[] IV = new byte[8]; 
     ICryptoTransform decryptor = RC2.CreateDecryptor(pbeKey, IV); 

     MemoryStream msDecrypt = new MemoryStream(); 
     CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Write); 

     csDecrypt.Write(input, 0, originalSize); 
     // csDecrypt.FlushFinalBlock(); 

     char[] decrypted = new char[input.Length]; 
     decrypted = System.Text.Encoding.UTF8.GetChars(msDecrypt.ToArray()); 
     return msDecrypt.ToArray(); 

    } 

숯 [] decrypted 파일이 </LudoData>로 끝나는 제외하고, 해독 된 전체 파일을 반환하고, I 만 해독하면됩니다 첫 번째 문자는 <입니다.

나는 여러 가지 길이로 놀았으며 아무것도 바뀌지 않았습니다. 내 구체적인 경우에 input 길이는 11296이며 originalSize 크기는 11290입니다. 그러나 decrypted은 암호 해독시 크기가 으로 끝납니다. 뭐라 구요!

답변

6

Flush()를 주석 처리 한 이유가 있습니까? 스트림을 완전히 닫으려고 했습니까?

+0

그는 두 가지 모두에서 최종 블록을 플러시해야한다는 것을 의미하는 두 가지 암호화 스트림에 모두 쓰고 있습니다. – Will

+0

런타임 오류로 인해 내가 고정되어 있고 플러시에 대해 잊어 버렸기 때문에 주석을 달았습니다. 이것은 어떻게 든 모든 것을 해결했습니다. 나는 전혀 이해하지 못한다. 그러나 고마워! – Mark

+0

그래, 비참한 플러시 문제가 다시 머리를 사로 잡는다. 나는이 많은 시간을 전에 만났다. 사실, 나는 그 다음 BAM을 다 OK입니다 생각하는 내 dev에 서버 작업 및 했어요! 그것은 똑같은 정확한 데이터로도 생산 환경에서 머리를 되찾았습니다! 미친, 응? 그것은 모두 플러시를 잊기 때문이었습니다. –

0

한숨에, 나는이 전투를 약 한 달 전에했고 매우 비슷한 이슈를 가지고 있었다. ToArray가 내 솔루션이었다.

당신은 이상한 물건을 여기에서하고 있습니다. 정확히 모르겠습니다. 당신은 cryptostream을 사용할 필요가 없을 때, 기이 한 이유로 원래 길이를 추적하고 비추천 클래스를 사용하고 있습니다. 문제는 패딩, 잘못된 가정 (originalLength로 입증 됨) 및 잘못된 스트림 처리 (복잡 할 수 있음)의 조합 일 가능성이 큽니다. 대신이 시도 :

암호화 :

var rij = RijndaelManaged.Create(); 
rij.Mode = CipherMode.CBC; 
rij.BlockSize = 256; 
rij.KeySize = 256; 
rij.Padding = PaddingMode.ISO10126; 
var pdb = new Rfc2898DeriveBytes(password, 
      Encoding.Default.GetBytes("lolwtfbbqsalt" + password)); 
var enc = rij.CreateEncryptor(pdb.GetBytes(rij.KeySize/8), 
      pdb.GetBytes(rij.BlockSize/8)); 
return enc.TransformFinalBlock(unencryptedBytes, 0, unencryptedBytes.Length); 

해독 :

// throws a cryptographic exception if password is wrong 
var rij = RijndaelManaged.Create(); 
rij.Mode = CipherMode.CBC; 
rij.BlockSize = 256; 
rij.KeySize = 256; 
rij.Padding = PaddingMode.ISO10126; 
var pdb = new Rfc2898DeriveBytes(password, 
      Encoding.Default.GetBytes("lolwtfbbqsalt" + password)); 
var dec = rij.CreateDecryptor(pdb.GetBytes(rij.KeySize/8), 
      pdb.GetBytes(rij.BlockSize/8)); 
return dec.TransformFinalBlock(encryptedBytes, 0, 
      encryptedBytes.Length); 

공지 사항이 두 가지 방법에서 다른 유일한 것은 CreateEncryptor와 /와 CreateDecryptor, 당신은 중복을 많이을 리팩토링 할 수 있습니다. 또한 바이트 배열을 알아 내서 스트림을 사용할 필요없이 바이트 배열을 가져옵니다. 그것도 RC2보다 조금 더 안전합니다. 소금이 더 무작위 인 경우 더욱 그렇습니다.

+0

RC2를 사용 중입니다. RC2 암호화 파일을 사용하는 C++ 응용 프로그램과도 호환되어야하기 때문입니다. – Mark