2009-07-06 20 views
7

Ich brauche zwei Methoden zum Verschlüsseln und eine zum Entschlüsseln einer XML-Datei mit einem Schlüssel = "Hallo Welt", der Schlüssel Hallo Welt sollte verwendet werden, um die XML-Datei zu verschlüsseln und zu entschlüsseln.Diese Methoden sollten funktionieren auf allen Maschinen !!! Alle Verschlüsselungsmethoden reichen aus. XML-Dateiinhalte unter:C# Verschlüsseln einer XML-Datei

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

Können einige geben Sie mir eine Probe Das Problem ist die Msdn Probe encyptions eine XML-Datei machen verschlüsselt gespeichert, aber wenn ich auf einer anderen Maschine zu entschlüsseln tut es nicht work.For Beispiel

Ich versuchte dieses Beispiel: How to: Encrypt XML Elements with Asymmetric Keys, aber hier gibt es irgendeine Art Sitzung und auf einer anderen Maschine sagt es schlechte Daten phewf!

+1

Bitte senden Sie ein kurzes Beispiel des Codes überprüfen, und was genau nicht funktioniert (zB ‚On line 12 I einen compilor Fehler 12345 erhalten‘ oder ‚während Laufzeit bekomme ich eine SecurityException in Zeile 15 '). – Treb

+1

schlechte daten durch enception klasse ah gut – abmv

+1

Müssen Sie die Daten verschlüsseln, um sie zu verbergen, oder nur die Daten vor Änderungen schützen? – sisve

Antwort

13

Wenn Sie den gleichen Schlüssel zum Verschlüsseln und Entschlüsseln möchten, sollten Sie eine symmetrische Methode verwenden (das ist die Definition, wirklich). Hier ist der nächste zu Ihrer Probe (gleiche Quelle). http://msdn.microsoft.com/en-us/library/sb7w85t6.aspx

Das veröffentlichte Beispiel funktioniert nicht, da sie nicht die gleichen Schlüssel verwenden. Nicht nur auf verschiedenen Rechnern: Das Programm zweimal auf demselben Rechner laufen zu lassen, sollte auch nicht funktionieren (funktionierte nicht für mich), weil sie jedes Mal verschiedene zufällige Schlüssel benutzen.
versucht diesen Code hinzugefügt nach dem Schlüssel zu erstellen:

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); 

Jetzt wird das Programm mit dem gleichen Schlüssel und Anfangsvektor verwendet wird, und Verschlüsseln und Entschlüsseln sollten auf allen Maschinen arbeiten.
Überlegen Sie auch, key zu algorithm umzubenennen, sonst ist dies sehr irreführend. Ich würde sagen, es ist ein schlechtes, nicht funktionierendes Beispiel von MSDN.

HINWEIS: PasswordDeriveBytes.GetBytes() wurde wegen schwerer als veraltet (Sicherheit) Fragen innerhalb der PasswordDeriveBytes Klasse. Der obige Code wurde neu geschrieben, um stattdessen die sicherere Klasse Rfc2898DeriveBytes zu verwenden (PBKDF2 statt PBKDF1). Code, der mit der obigen Angabe unter Verwendung von PasswordDeriveBytes generiert wurde, kann kompromittiert sein.

Siehe auch: Recommended # of iterations when using PKBDF2-SHA256?

+0

Ich habe dieses Beispiel versucht, Wenn ich auskommentieren nur entschlüsseln, dann verschlüsseln und dann auskommentieren verschlüsseln und die Entschlüsselung funktioniert nicht? Warum? – abmv

+0

Danke, verdammt diese msdn Jungs, nun hast du meinen Tag gerettet. Danke nochmal für deine Zeit und die Ressource. – abmv

+1

Ich habe Zeit, all diese komplexen Verschlüsselungskram zu verstehen. Ich versuchte tatsächlich zu verstehen, indem ich MSDN las, aber wenn sie es nicht richtig erklären können, wer sonst kann. Sie müssen nicht die ganze kryptographische Theorie verstehen, um eine Datei zu verschlüsseln. Gut .net hat Klassen und ich muss sie nur verwenden, um meine Zeit zu sparen! Und ich gebe Ihnen ein Beispiel, dann zumindest sollte es auf verschiedenen Maschinen funktionieren! – abmv

4

kühler sein würde, wenn Sie einen privaten Schlüssel verwendet, um das <lic> Element zu unterzeichnen und hinzugefügt, um das Ergebnis in die Datei (in einem <Hash> Elemente vielleicht). Dies würde es jedem ermöglichen, die XML-Datei zu lesen, falls Ihr Support die Lizenznummer oder das Verfallsdatum kennen muss, aber sie können keine Werte ohne den privaten Schlüssel ändern.

Der öffentliche Schlüssel, der zur Überprüfung der Signatur benötigt wird, wäre allgemein bekannt.

Klärung
Signieren von Code wird nur gegen Änderungen schützen, wird es keine Informationen halten sie versteckt. Ihre ursprüngliche Frage erwähnt Verschlüsselung, aber ich bin mir nicht sicher, ob es eine Voraussetzung ist, die Daten zu verstecken oder nur vor Änderungen zu schützen.

Beispielcode: (PrivateKey.key niemals veröffentlichen. ServerMethods werden nur benötigt, wenn die XML-Datei signiert wird, ClientMethods werden nur benötigt, wenn die XML-Datei überprüft wird.

)
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

Ich habe versucht, zwei Probe von msdn aber .. das Problem ist, ich kann es richtig auf einer diff-Maschine zu entschlüsseln. – abmv

3

Vor allem, wenn Sie den gleichen Schlüssel zum Verschlüsseln und Entschlüsseln verwenden möchten, sollten Sie bei symmetrischen Kryptographie aussehen. Bei der asymmetrischen Kryptographie unterscheiden sich die Schlüssel zum Verschlüsseln und Entschlüsseln. Nur damit Sie wissen - RSA ist asymmetrisch, TripleDES und Rijndael sind symmetrisch. Es gibt auch andere, aber .NET hat keine Standardimplementierungen für sie.

Ich würde empfehlen, die System.Security.Cryptography namespace zu studieren. Und ein bisschen über all das Zeug lernen. Es enthält alles, was Sie zum Verschlüsseln und Entschlüsseln von Dateien benötigen, sowie ein Passwort. Insbesondere könnte man in diesen Klassen interessieren:

  • CryptoStream
  • PasswordDeriveBytes
  • RijndaelManaged

Es gibt auch Beispiele für den Einsatz in MSDN für jeden von ihnen. Sie können diese Klassen verwenden, um jede Datei zu verschlüsseln, nicht nur XML. Wenn Sie jedoch nur einige wenige Elemente verschlüsseln möchten, können Sie sich den Namensraum System.Security.Cryptography.Xml ansehen. Ich sehe, Sie haben bereits einen Artikel darüber gefunden. Folgen Sie den Links auf dieser Seite und Sie werden mehr über diese Klassen erfahren.

2

dies ist, wie Sie digital signieren und XML-Dokumente Sign XML Documents

+0

siehe auch eine der ähnlichen Fragen, die ich hier aufgeworfen habe http://StackOverflow.com/Questions/1031856/digitally-sign-parts-of-a-xml-document – Eros

Verwandte Themen