2009-07-06 14 views
7

Potrzebuję dwóch metod, jeden do zaszyfrowania, a jeden do odszyfrowania pliku xml za pomocą klucza = "hello world", kluczowy świat hello powinien być użyty do zaszyfrowania i odszyfrowania pliku xml. Te metody powinny działać na wszystkich maszynach !!! Wszystkie metody szyfrowania zrobi. zawartość pliku XML poniżej:?C# Szyfrowanie pliku XML

<root> 
    <lic> 
     <number>19834209</number> 
     <expiry>02/02/2002</expiry> 
    </lic> 
</root> 

Można niektóre dać mi próbkę Kwestia jest przykładowe encyptions MSDN zrobić plik xml encypted ale kiedy odszyfrować na innym komputerze to nie work.For przykład

Próbowałem tej próbki: How to: Encrypt XML Elements with Asymmetric Keys, ale tutaj jest trochę sesji i na innej maszynie mówi złe dane phewf!

+1

proszę zamieścić krótki przykład kodu, a co dokładnie nie działa (np „Na linii 12 pojawia się błąd compilor 12345” lub „podczas środowisko wykonawcze Otrzymuję SecurityException na linii 15 '). – Treb

+1

złe dane zgłoszone przez klasę encypli ah well – abmv

+1

Czy chcesz zaszyfrować dane, aby je ukryć, lub po prostu chronić dane przed zmianami? – sisve

Odpowiedz

13

Jeśli chcesz ten sam klucz do szyfrowania i odszyfrowywania, powinieneś użyć metody symetrycznej (to jest definicja). Oto najbliższa próbka (to samo źródło). http://msdn.microsoft.com/en-us/library/sb7w85t6.aspx

Wysłana próbka nie działa, ponieważ nie używa tych samych kluczy. Nie tylko na różnych maszynach: uruchomienie programu na tym samym komputerze dwa razy też nie powinno działać (nie działa dla mnie), ponieważ za każdym razem używają różnych losowych kluczy.
Spróbuj dodać ten kod po utworzeniu klucza:

key = new RijndaelManaged(); 

string password = "Password1234"; //password here 
byte[] saltBytes = Encoding.UTF8.GetBytes("Salt"); // salt here (another string) 
var p = new Rfc2898DeriveBytes(password, saltBytes); //TODO: think about number of iterations (third parameter) 
// sizes are devided by 8 because [ 1 byte = 8 bits ] 
key.IV = p.GetBytes(key.BlockSize/8); 
key.Key = p.GetBytes(key.KeySize/8); 

Teraz program jest przy użyciu tego samego klucza i wektor początkowy i szyfrowania i deszyfrowania powinien działać na wszystkich maszynach.
Należy również rozważyć zmianę nazwy na key na algorithm, w przeciwnym razie jest to bardzo mylące. Powiedziałbym, że to zły, nie działający dobrze przykład z MSDN.

UWAGA: PasswordDeriveBytes.GetBytes() została zaniechana z powodu poważnych problemów (Security) w obrębie klasy PasswordDeriveBytes. Powyższy kod został przepisany w celu użycia bezpieczniejszej klasy Rfc2898DeriveBytes (PBKDF2 zamiast PBKDF1). Kod wygenerowany przy użyciu powyższego kodu przy użyciu PasswordDeriveBytes może zostać naruszony.

Zobacz także: Recommended # of iterations when using PKBDF2-SHA256?

+0

Próbowałem tej próbki, jeśli komentuję tylko odszyfrować, a następnie szyfrować, a następnie skomentować zaszyfrować i odszyfrowywanie nie działa? Czemu? – abmv

+0

Dzięki, cholera, chłopaki z msdn, uratowaliście mi mój dzień. Dziękuję wam za poświęcony czas i zasoby. – abmv

+1

Jak mam czas, aby zrozumieć wszystkie te skomplikowane szyfrowanie rzeczy. Byłem w rzeczywistości próbując zrozumieć, czytając MSDN, ale jeśli nie potrafią wyjaśnić to poprawnie, to kto może. Nie musisz rozumieć całej Teorii Kryptograficznej, aby encypptować plik. Cóż. .net ma klasy i po prostu potrzebuję ich użyć, aby zaoszczędzić czas! I dadzą ci przykład, a przynajmniej powinien działać na różnych maszynach! – abmv

4

Byłoby chłodniej jeśli użyto klucza prywatnego do podpisania element <lic> i dodaje wynik do pliku (w <hash> elementu chyba). Dzięki temu każdy może przeczytać plik xml, na wypadek gdyby twoje wsparcie musiało znać numer licencji lub datę wygaśnięcia, ale nie może zmienić żadnych wartości bez klucza prywatnego.

Klucz publiczny potrzebny do zweryfikowania podpisu byłby powszechnie znany.

Wyjaśnienie
Podpisanie kod będzie tylko chronić je przed zmianami, nie będzie przechowywać wszelkie informacje w nim ukryte. Twoje pierwotne pytanie wspomina o szyfrowaniu, ale nie jestem pewien, czy jest to konieczne, aby ukryć dane, czy po prostu chronić je przed modyfikacją.

Przykładowy kod: (Nigdy nie publikuj PrivateKey.key. ServerMethods są potrzebne tylko podczas podpisywania pliku xml, ClientMethods są potrzebne tylko podczas weryfikacji pliku xml.)

using System; 
using System.Diagnostics; 
using System.IO; 
using System.Security.Cryptography; 
using System.Text; 
using System.Xml; 

public static class Program { 
    public static void Main() { 
     if (!File.Exists("PublicKey.key")) { 
      // Assume first run, generate keys and sign document. 
      ServerMethods.GenerateKeyPair(); 

      var input = new XmlDocument(); 
      input.Load("input.xml"); 
      Debug.Assert(input.DocumentElement != null); 

      var licNode = input.DocumentElement["lic"]; 
      Debug.Assert(licNode != null); 

      var licNodeXml = licNode.OuterXml; 
      var signedNode = input.CreateElement("signature"); 
      signedNode.InnerText = ServerMethods.CalculateSignature(licNodeXml); 
      input.DocumentElement.AppendChild(signedNode); 

      input.Save("output.xml"); 
     } 

     if (ClientMethods.IsValidLicense("output.xml")) { 
      Console.WriteLine("VALID"); 
     } else { 
      Console.WriteLine("INVALID"); 
     } 
    } 

    public static class ServerMethods { 
     public static void GenerateKeyPair() { 
      var rsa = SharedInformation.CryptoProvider; 

      using (var keyWriter = File.CreateText("PublicKey.key")) 
       keyWriter.Write(rsa.ToXmlString(false)); 

      using (var keyWriter = File.CreateText("PrivateKey.key")) 
       keyWriter.Write(rsa.ToXmlString(true)); 
     } 

     public static string CalculateSignature(string data) { 
      var rsa = SharedInformation.CryptoProvider; 
      rsa.FromXmlString(File.ReadAllText("PrivateKey.key")); 

      var dataBytes = Encoding.UTF8.GetBytes(data); 
      var signatureBytes = rsa.SignData(dataBytes, SharedInformation.HashAlgorithm); 
      return Convert.ToBase64String(signatureBytes); 
     } 
    } 

    public static class ClientMethods { 
     public static bool IsValid(string data, string signature) { 
      var rsa = SharedInformation.CryptoProvider; 
      rsa.FromXmlString(File.ReadAllText("PublicKey.key")); 

      var dataBytes = Encoding.UTF8.GetBytes(data); 
      var signatureBytes = Convert.FromBase64String(signature); 
      return rsa.VerifyData(dataBytes, SharedInformation.HashAlgorithm, signatureBytes); 
     } 

     public static bool IsValidLicense(string filename) { 
      var doc = new XmlDocument(); 
      doc.Load(filename); 

      var licNode = doc.SelectSingleNode("/root/lic") as XmlElement; 
      var signatureNode = doc.SelectSingleNode("/root/signature") as XmlElement; 
      if (licNode == null || signatureNode == null) return false; 

      return IsValid(licNode.OuterXml, signatureNode.InnerText); 
     } 
    } 

    public static class SharedInformation { 
     public static int KeySize { 
      get { return 1024; } 
     } 

     public static string HashAlgorithm { 
      get { return "SHA512"; } 
     } 

     public static RSACryptoServiceProvider CryptoProvider { 
      get { return new RSACryptoServiceProvider(KeySize, new CspParameters()); } 
     } 
    } 
} 
+0

Próbowałem dwóch próbek z msdn, ale .. problem polega na tym, że mogę go odpowiednio rozdzielić na maszynie różnicowej. – abmv

3

Przede wszystkim, jeśli chcesz używać tego samego klucza do szyfrowania i deszyfrowania, należy spojrzeć na kryptografii symetrycznej. Kryptografia asymetryczna występuje wtedy, gdy klucze do szyfrowania i deszyfrowania są różne. Tylko dlatego, że wiesz - RSA jest asymetryczna, TripleDES i Rijndael są symetryczne. Są też inne, ale .NET nie ma dla nich domyślnych implementacji.

Zalecałbym studiowanie System.Security.Cryptography namespace. I trochę się o tym wszystkim uczę. Ma wszystko, czego potrzeba do szyfrowania i odszyfrowywania plików, a także generowania hasła. W szczególności, może być zainteresowany w tych klasach:

  • CryptoStream
  • PasswordDeriveBytes
  • RijndaelManaged

Istnieją również przykłady użycia w MSDN dla każdej z nich. Możesz użyć tych klas do zaszyfrowania dowolnego pliku, nie tylko XML. Jeśli jednak chcesz zaszyfrować tylko wybrane elementy, możesz zajrzeć do przestrzeni nazw System.Security.Cryptography.Xml. Widzę, że znalazłeś już jeden artykuł na ten temat. Śledź linki na tej stronie, a dowiesz się więcej o tych klasach.

2

ten sposób można podpisać cyfrowo i zweryfikować dokumenty XML Sign XML Documents

+0

Zobacz także jedno z podobnych pytań, które podniosłem tutaj http://stackoverflow.com/questions/1031856/digitally-sign-parts-of-a-xml-document – Eros