2017-12-11 2 views
1

Ich versuche, eine einfache Klasse zum Verschlüsseln und Entschlüsseln von Daten in C# zu testen. JedochPadding ist ungültig und kann nicht entfernt werden AES PKCS7

`

{ [TestFixture] 
    public class CryptTest 
    { 
     [Test] 
     public void TestMethod() 
     { 
      String text = "Hello World!"; 

      String crypt = EncryptionService.Encrypt(text, Config.KEY_STRING); 
      Console.WriteLine(crypt); 
      String clear = EncryptionService.Decrypt(crypt, Config.KEY_STRING); 
      Console.WriteLine(clear); 
      Assert.That(clear, Is.EqualTo(text)); 


     } 

`, erhalte ich die folgende Ausnahme:

Message: System.Security.Cryptography.CryptographicException : Padding is invalid and cannot be removed. 

mit dem Stapel:

 StackTrace " at System.Security.Cryptography.CapiSymmetricAlgorithm.DepadBlock(Byte[] block, Int32 offset, Int32 count)\r\n at System.Security.Cryptography.CapiSymmetricAlgorithm.TransformFinalBlock(Byte[] inputBuffer, Int32 inputOffset, Int32 inputCount)\r\n at System.Security.Cryptography.CryptoStream.Read(Byte[] buffer, Int32 offset, Int32 count)\r\n at System.IO.StreamReader.ReadBuffer()\r\n at System.IO.StreamReader.ReadToEnd()\r\n at InsuranceMidAm.Services.EncryptionService.Decrypt(String cipher, String key) in C:\\Visual Studio Projects\\InsuranceMidAm\\InsuranceMidAm\\Services\\EncryptionService.cs:line 72\r\n at InsuranceMidAm.Tests.CryptTest.TestMethod() in C:\\Visual Studio Projects\\InsuranceMidAm\\InsuranceMidAm.Tests\\CryptTest.cs:line 20" string 

Dies ist die Klasse im Test:

namespace InsuranceMidAm.Services 
{ 
    public class EncryptionService 
    { 
     // Reference: https://stackoverflow.com/questions/273452/using-aes-encryption-in-c-sharp 
     public static String Encrypt(String text, String key) 
     { 

      byte[] value = UTF8Encoding.UTF8.GetBytes(text); 
      byte[] crypt; 
      byte[] iv; 
      using (Aes myAes = Aes.Create()) 
      { 

       myAes.KeySize = 256; 
       myAes.Mode = CipherMode.CBC; 
       myAes.Key = HexToBin(key); 
       myAes.GenerateIV(); 
       myAes.Padding = PaddingMode.PKCS7; 

       using (MemoryStream ms = new MemoryStream()) 
       { 
        using (CryptoStream cs = new CryptoStream(ms, myAes.CreateEncryptor(), CryptoStreamMode.Write)) 
        { 
         cs.Write(value, 0, value.Length); 
         cs.FlushFinalBlock(); 
         crypt = ms.ToArray(); 
        } 
       } 
       iv = myAes.IV; 
       myAes.Clear(); 
      } 
      return ByteArrayToString(crypt) + ":" + ByteArrayToString(iv); 

     } 

     public static string Decrypt(String cipher, String key) 
     { 
      String outputString = ""; 
      byte[] ivBytes = HexToBin(getIV(cipher)); 
      byte[] valBytes = HexToBin(getSSN(cipher)); 

      using (Aes myAes = Aes.Create()) 
      { 
       int size = valBytes.Count(); 

       myAes.KeySize = 256; 
       myAes.Mode = CipherMode.CBC; 
       myAes.Key = HexToBin(key); 
       myAes.IV = ivBytes; 
       myAes.Padding = PaddingMode.PKCS7; 

       char[] output = new char[256]; 

       ICryptoTransform myDecrypter = myAes.CreateDecryptor(myAes.Key, myAes.IV); 

       using (MemoryStream memory = new MemoryStream(ivBytes)) 
       { 
        using (CryptoStream cryptStream = new CryptoStream(memory, myDecrypter, CryptoStreamMode.Read)) 
        { 
         using (StreamReader reader = new StreamReader(cryptStream)) 
         { 

          outputString = reader.ReadToEnd(); 
         } 

         return outputString; 
        } 
       } 

      } 
     } 

     private static byte[] HexToBin(String hexString) 
     { 


      int charCount = hexString.Length; 
      byte[] output = new byte[charCount/2]; 
      for (int i = 0; i < charCount; i += 2) 
      { 
       output[i/2] = Convert.ToByte(hexString.Substring(i, 2), 16); 
      } 


      return output; 
     } 

     private static String getSSN(String cipher) 
     { 
      int delimiterIndex = cipher.IndexOf(":"); 
      String SSN = cipher.Substring(0, delimiterIndex); 
      return SSN; 
     } 


     private static String getIV(String cipher) 
     { 
      int delimiterIndex = cipher.IndexOf(":"); 
      String IV = cipher.Substring(delimiterIndex + 1); 
      return IV; 
     } 




     // Reference: https://stackoverflow.com/questions/311165/how-do-you-convert-a-byte-array-to-a-hexadecimal-string-and-vice-versa 
     private static string ByteArrayToString(byte[] ba) 
     { 
      string hex = BitConverter.ToString(ba); 
      return hex.Replace("-", ""); 
     } 

    } 
} 

Linie 73 (wo die Ausnahme aufgetreten ist) ist das Ende der using-Blöcke für den Stream in der Entschlüsselungs-Methode:

using (StreamReader reader = new StreamReader(cryptStream)) 
        { 

         outputString = reader.ReadToEnd(); 
        } 

ich die following question verweisen, kann aber mein Problem nicht beheben.

Ursprünglich wurden die Daten in einer PHP-Anwendung verschlüsselt und mit einer C# -Anwendung entschlüsselt (mit fast der gleichen Entschlüsselungsmethode wie oben). Nun möchte ich die Daten mit C# sowohl verschlüsseln als auch entschlüsseln. Allerdings muss ich die vorhandenen Daten (die mit PHP verschlüsselt wurden) immer noch korrekt entschlüsseln können, sodass ich die Entschlüsselungsmethode nicht zu sehr modifizieren würde.

Jeder Rat würde geschätzt werden.

Antwort

1

Sie haben kleinere Fehler hier:

ICryptoTransform myDecrypter = myAes.CreateDecryptor(myAes.Key, myAes.IV); 
using (MemoryStream memory = new MemoryStream(ivBytes)) 

Sie Ihren Pass IV-Wert zu entschlüsseln, anstatt wirklich verschlüsselten Bytes. Fix:

ICryptoTransform myDecrypter = myAes.CreateDecryptor(myAes.Key, myAes.IV); 
using (MemoryStream memory = new MemoryStream(valBytes)) 
+0

Vielen Dank; das hat es gelöst. Sieht aus wie diverse Fehler die gleiche Ausnahme verursachen können; große Beobachtung. :) – KellyMarchewa

+1

@Kelly Ja, jeder Fehler, der das Ende des entschlüsselten Textes stört, führt zu einer 'Bad Padding'-Ausnahme, ebenso wie die Verwendung des falschen Padding-Typs. In beiden Fällen kann der Entschlüsselungscode das korrekte Auffüllen nicht erkennen und löst die Ausnahme aus. – rossum

+1

@KellyMarchewa, da Sie zufällig generierten Wert zum Entschlüsseln übergeben (IV) - Sie könnten irgendeine Art von Fehler erhalten. Wenn Sie Glück haben und das Padding korrekt war, könnten Sie zum Beispiel Müll entschlüsseln. Und wenn Sie super glücklich sind und generiert IV ist das gleiche wie verschlüsselte Daten - es kann sogar richtig entschlüsselt werden. – Evk

Verwandte Themen