Diskuze: Vytovření objektu v metodě nebo jako parametr - problém

C# .NET .NET (C# a Visual Basic) Vytovření objektu v metodě nebo jako parametr - problém American English version English version

Avatar
Petr Nymsa
Redaktor
Avatar
Petr Nymsa:

Ahoj, potýkám se se zvláštním problémem a nevím co s tím. Asi jen nějaká moje neznalost, každopádně. Snažím se šifrovat data. Šifrování a dešifrování skrz

Šifrování probíhá takto

public byte[] Encrypt(string strText, SymmetricAlgorithm alg)
      {
          MemoryStream ms = new MemoryStream();

          using (CryptoStream cryptoStream = new CryptoStream(ms,alg.CreateEncryptor(),CryptoStreamMode.Write))
          {
              using (StreamWriter sw = new StreamWriter(cryptoStream))
              {
                  sw.WriteLine(strText);
              }
          }
          byte[] encrypted = ms.ToArray();
          ms.Close();
          return encrypted;
      }

a dešifrování

public string Decrypt(byte[] encryptText, SymmetricAlgorithm alg)
      {
          Debug.WriteLine(Convert.ToBase64String(alg.Key));
          MemoryStream ms = new MemoryStream(encryptText);
          string data;
          using (CryptoStream cryptoStream = new CryptoStream(ms, alg.CreateDecryptor(), CryptoStreamMode.Read))
          {
              using (StreamReader sr = new StreamReader(cryptoStream))
              {
                  data = sr.ReadLine();
              }
          }
          ms.Close();
          return data;
      }

ted problém
Metody volám následovně - vytvořím SymmetricAlgorithm a předám metodě. Vše proběhne v pořádku.

SymmetricAlgorithm alg = SymmetricAlgorithm.Create();
              alg.Key = key;
              byte[] encrypted = cryptProvider.Encrypt(input, alg);
              string decrypted = cryptProvider.Decrypt(encrypted, alg);

v promměnné key mám načtený symetrický klíč. Každopdáně když chci změnit metody do podoby, kdy nepředám třídu SymmetricAlgo­rithm ale pouze byte[] klíč tak to prostě a jednoduše nefunguje. Viz kód

public byte[] Encrypt(string strText, byte[] key)
        {
            SymmetricAlgorithm alg = SymmetricAlgorithm.Create();
            alg.Key = key;
            MemoryStream ms = new MemoryStream();

            using (CryptoStream cryptoStream = new CryptoStream(ms, alg.CreateEncryptor(), CryptoStreamMode.Write))
            {
                using (StreamWriter sw = new StreamWriter(cryptoStream))
                {
                    sw.WriteLine(strText);
                }
            }
            byte[] encrypted = ms.ToArray();
            ms.Close();
            return encrypted;
        }

        public string Decrypt(byte[] encryptText, byte[] key)
        {
            SymmetricAlgorithm alg = SymmetricAlgorithm.Create();
            alg.Padding = PaddingMode.Zeros;
            alg.Key = key;
            Debug.WriteLine(Convert.ToBase64String(alg.Key));
            MemoryStream ms = new MemoryStream(encryptText);
            string data;
            using (CryptoStream cryptoStream = new CryptoStream(ms, alg.CreateDecryptor(), CryptoStreamMode.Read))
            {
                using (StreamReader sr = new StreamReader(cryptoStream))
                {
                    data = sr.ReadLine();
                }
            }
            ms.Close();
            return data;
        }

Několik problémů

  1. Hází Exception - Padding is invalid and cannot be removed.
  • vyřešeno pomocí PaddingMode.Zeros (přitom u první metody, tj kde předávám objekt) nebylo třeba
  1. po změně PaddingMode dešifrování nefunguje tak jak má ) tj vrací to úplné nesmysly. Někdo rozumné vysvětlení ?

Díky moc

Odpovědět 5.1.2015 21:28
Pokrok nezastavíš, neusni a jdi s ním vpřed
Avatar
rwn
Člen
Avatar
Odpovídá na Petr Nymsa
rwn:

Ahoj, tak jsem si to párkrát zkusil a přišel jsem na to. :) Problém je v tom, že když si nějakou zprávu zakóduješ, tak se ti při každém vytvoření instance SymmetricAlgorithm zakóduje do jiného pole encrypted nějakým vnitřním systémem, který se vztahuje k tvojí konkrétní třídě alg. Nějaký systém podle kterého se to uvnitř zpracuje je ve vlastnosti .IV (tahle vlastnost se vždy náhodně generuje při vytvoření instance třídy SymmetricAlgorithm ) a při dekódování je stejně tak potřeba jako .Key. Takže v zakódování se ti používá nějaké vnitřní zakódování do něčeho a při dekódování se použije zas něco úplně jiného na dekódování, proto ti to dává špatné výsledky. Napadá mě teda řešení, udělat si nějaké uložiště (třeba private proměnnou), kam si v Encrypt() uložíš alg.IV a následně jí v metodě Decrypt přiřadíš k nově vytvořené alg.IV, při tomto řešení není ani žádný problém s vlastností .Padding, takže jí nemusíš přenastavovat. Teoreticky, by sis ale mohl už raději udělat v té tvojí třídě cryptProvider udělat private proměnnou SymmetricAlgorithm alg a v konstruktoru jí deklarovat, ale tak to asi dost záleží i na tom, co s tím chceš dál dělat. :)

Akceptované řešení
+20 Zkušeností
Řešení problému
Nahoru Odpovědět 6.1.2015 6:06
Co můžeš naprogramovat dnes, neodkládej na zítřek.
Avatar
Petr Nymsa
Redaktor
Avatar
Odpovídá na rwn
Petr Nymsa:

Přesně jak jsem říkal, neznalost :) díky

Nahoru Odpovědět 6.1.2015 9:30
Pokrok nezastavíš, neusni a jdi s ním vpřed
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 3 zpráv z 3.