2013-08-22 3 views
1

저는 C#에서 AESCryptoServiceProvider를 사용하기위한 연구를 해왔습니다. 지금까지는 작동하는 것으로 보이는 구현이 있습니다. 그러나 초기화 벡터에 대한 나의 이해는 페이로드와 키가 같을 때 제 암호 텍스트가 동일하지 않도록 보호해야한다는 것입니다.하지만 잘못된 것으로 나타납니다. 내 초기화 벡터를 변경해도이 함수의 결과에는 전혀 영향을 미치지 않는 것 같습니다. 지금 CBC 모드를 다시 변경 @owlstead에서 다음과 같은 사항을 한 내 암호화 기능의내 AES 초기화 벡터는 C#의 AESCryptoServiceProvider와 아무런 관련이없는 것처럼 보입니다.

public string EncryptString(string toEncrypt, byte[] encryptionKey, byte[] iv) 
{ 
    var toEncryptBytes = Encoding.Default.GetBytes(toEncrypt); 
    using (var aes = new AesCryptoServiceProvider()) 
    { 
     aes.Key = encryptionKey; 
     aes.Mode = CipherMode.CBC; 
     aes.Padding = PaddingMode.PKCS7; 
     //aes.GenerateIV(); 
     aes.IV = iv; 

     using (var encryptor = aes.CreateEncryptor(encryptionKey, aes.IV)) 
     using (var ms = new MemoryStream()) 
     { 
      using (var cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write)) 
      using (var bWriter = new BinaryWriter(cs)) 
      { 
       bWriter.Write(aes.IV, 0, aes.IV.Length); 
       bWriter.Write(toEncryptBytes, 0, toEncryptBytes.Length); 
       cs.FlushFinalBlock(); 
      } 
      return Convert.ToBase64String(ms.ToArray()); 
     } 
    } 
} 

public string DecryptString(string toDecrypt, byte[] encryptionKey, byte[] iv) 
{ 
    using (var aes = new AesCryptoServiceProvider()) 
    { 
     aes.Key = encryptionKey; 
     aes.Mode = CipherMode.CBC; 
     aes.Padding = PaddingMode.PKCS7; 
     var toDecryptBytes = Convert.FromBase64String(toDecrypt); 

     Array.Copy(toDecryptBytes, 0, iv, 0, iv.Length); 
     aes.IV = iv; 

     using (var ms = new MemoryStream()) 
     { 
      using (var cs = new CryptoStream(ms, aes.CreateDecryptor(aes.Key, iv), CryptoStreamMode.Write)) 
      using (var binWriter = new BinaryWriter(cs)) 
      { 
       binWriter.Write(toDecryptBytes, iv.Length, toDecryptBytes.Length - iv.Length); 
      } 
      return Encoding.Default.GetString(ms.ToArray()); 
     } 
    } 
} 

새로운 버전 : 여기

내 기능입니다. 이것은 CBC를 사용하여 올바르게 작동하는 것처럼 보입니다.

public string EncryptString(string toEncrypt, byte[] encryptionKey) 
{ 
    var toEncryptBytes = Encoding.Default.GetBytes(toEncrypt); 
    using (var aes = new AesCryptoServiceProvider()) 
    { 
     aes.Key = encryptionKey; 
     aes.Mode = CipherMode.CBC; 
     aes.Padding = PaddingMode.PKCS7; 
     aes.GenerateIV(); 

     using (var encryptor = aes.CreateEncryptor(encryptionKey, aes.IV)) 
     using (var ms = new MemoryStream()) 
     { 
      ms.Write(aes.IV, 0, aes.IV.Length); 
      using (var cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write)) 
      using (var bWriter = new BinaryWriter(cs)) 
      { 
       bWriter.Write(toEncryptBytes, 0, toEncryptBytes.Length); 
       cs.FlushFinalBlock(); 
      } 
      return Convert.ToBase64String(ms.ToArray()); 
     } 
    } 
} 
+0

"이 기능의 결과에는 전혀 영향을 미치지 않는 것 같습니다." 동일한 입력이 동일한 출력을 제공한다는 것을 의미합니까? – TomF

+0

다른 IV 입력은 동일한 출력을 제공합니다. 예를 들어, "AAABBBCCCDDDTOIGJAEOITGJIOEAJTGA"키와 "AAABBBCCCDDDTOI5"의 키를 사용하여 일부 데이터를 암호화합니다. 이것은 내 암호 텍스트로 "WIZzTtGBynNs/lN7Yqs4Gb8hDHInW4fgpCTOWUifIwc ="를 다시 제공합니다. 이 키를 동일한 IV이지만 다른 IV를 사용하는 해독 방법으로 전달하여 원본 텍스트를 다시 가져 왔습니다. 언급 할 가치가있는 또 다른 포인트는 EncryptString 함수에 대한 호출에서 IV를 변경하면 동일한 암호 텍스트가 생성된다는 것입니다. –

+0

이전에 댓글을 달았지만 게시되지 않았습니다. 우선 IV 선택은 불필요하게 복잡합니다. 단지 0 배열의 첫 번째 바이트 만 설정할 수 있습니다. 또한 AES 모듈이 제대로 작동하지 않는다고 확신하는 경우 IV가 항상 0 또는 디버그로 표시 될 수 있습니다. – TomF

답변

2

당신은 적어도 암호화 기능에 대한 잘못된 순서로 CryptoStreamBinaryWriter를 가하고 있습니다. 현재 IV를 암호화하고 있으며 IV는 암호문 앞에 놓여 있어야합니다.

IV는 암호화되기 전에 일반 텍스트와 XOR됩니다. 자, 이것은 평문을 제로로한다는 것을 의미합니다 : 당신은 0 값 블록을 암호화하고 있습니다.

0

CipherMode.ECB 모드는 IV 인수를 사용하지 않는 것입니다. 즉, IV가 전달 된 것과 관계없이 결과가 동일 함을 의미합니다. ECB는 초기 벡터로 개념이 필요하지 않기 때문에 가능합니다. 후속 벡터도 없습니다. ECB 블록을 마스킹하려면 암호화가 정상이되기 전에 블록을 수동으로 XOR하십시오. CipherMode.CBC로 변경하는 동안 IV가 중요합니다. 이후 블록은 체인을 형성하는 것처럼 이전의 암호화 된 블록과 XOR됩니다.