|
Kategorien |
| |
|
|
Allgemein |
|
|
|
|
Autoren |
|
|
|
|
Autor:
Till Groos |
|
Zeitliche Beschränkung der Laufzeit von Software
Es gibt einige Möglichkeiten, Software nur für bestimmte Zeit laufen zu lassen. Sie können Einträge zur Registry hinzufügen oder Software schon beim Kompilieren nur bis zu einen bestimmten Datum funktionieren lassen. Einträge in der Registry kann man jedoch ändern und Ihre 30 Tage Testversion wollen Sie auch nicht jede Woche neu kompilieren. Was aber, wenn Ihre Software nur in einer bestimmten Zeitspanne lauffähig sein soll, variable von Ihnen bestimmt und sicher?
Die Lösung hier benutzt den ?System.Security.Cryptography? und den ?System.Runtime.Serialization.Formatters.Binary? Namespace. Die Idee ist, eine Schlüsseldatei zu generieren, welche dann jeweils mit der Software ausgeliefert wird.
Die Vorgehensweise
Da wir es sicher machen wollen, definieren wir uns eine eigene Struktur ?Zeitspanne?, die die Zeitspanne repräsentiert.
[Serializable] public struct Zeitspanne : ISerializable { public long s, e; public Zeitspanne(long s, long e) { this.s = s; this.e = e; } public Zeitspanne(SerializationInfo info, StreamingContext context) { s = info.GetInt64("s"); e = info.GetInt64("e"); } public void GetObjectData(SerializationInfo info, StreamingContext context) { info.AddValue("s", s); info.AddValue("e", e); } }
|
Um diese Datei vor Bösewichtern zu Schützen, verschlüsseln wir unsere Daten noch mit dem RijndaelManaged-Verfahren. Dazu brauchen wir eine Instanz der Klasse ?RijndaelManaged, ein Byte-Array als geheimen Schlüssel und ein Byte-Array als Vektor zur Verschlüsselung. Aber nicht genug der Sicherheit. Wir serialisieren unsere ?TimeSpan? auch binär, was in Kombination mit der Verschlüsselung wohl sicher genug sein sollte.
Hier der ganze Code zur Verschlüsselung (VB.NET)
Imports System Imports System.IO Imports System.Runtime.Serialization Imports System.Runtime.Serialization.Formatters.Binary Imports System.Security.Cryptography
?Die Zeitspanne Dim mySpan As New Zeitspanne(Me.dtpStart.Value.Ticks, Me.dtpStop.Value.Ticks) ?Unsere Verschlüsselungsmethode Dim RMCrypto As New RijndaelManaged ?GEHEIM Dim Key As Byte() = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} ?init Verktor Dim IV As Byte() = {1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0} ?hilfsstream Dim s As New MemoryStream ?der eigentliche Stream zum Verschlüsseln Dim CryptStream As New CryptoStream(New FileStream("key.bin", FileMode.OpenOrCreate), RMCrypto.CreateEncryptor(Key, IV), CryptoStreamMode.Write)
?Zum Serialisieren Dim b As BinaryFormatter = New BinaryFormatter Try ?erst Serialisieren b.Serialize(s, mySpan) ?dann den Inhalt verschlüsseln For i As Int32 = 0 To s.ToArray.Length - 1 CryptStream.WriteByte(s.ToArray(i)) Next MessageBox.Show("Keyfile generiert", "Bestätigung") Catch ex As Exception MessageBox.Show(ex.ToString, ex.GetType.ToString) Finally CryptStream.Flush() CryptStream.Close() s.Flush() s.Close() End Try
|
Um das ganze wieder auszulesen, muss man alle Schritte rückwärts ausführen. Ein Sache muss man noch wissen: der BinaryFormatter kann nur aus einer Datei deserialisieren. Deshalb muss man der Cryptostream erst in eine temporäre Datei Zwischenspeichern. Leider ist dies eine ziemliche Schwachstelle in unserem Sicherheitssystem. Trotz intensiven Bemühens funktionierte das Deserialisieren nicht aus dem MemoryStream. Hier jetzt der Code (C#)
using System; using System.IO; using System.Runtime.Serialization; using System.Runtime.Serialization.Formatters.Binary;
//aktuelles Datum long jetzt; // unsere Zeitspanne Zeitspanne mySpan; RijndaelManaged RMCrypto = new RijndaelManaged(); byte[] Key = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; byte[] IV = {1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0}; Stream s = File.Open(@"key.bin", FileMode.Open, FileAccess.Read, FileShare.Read); jetzt = s.Length; CryptoStream CryptStream = new CryptoStream(s, RMCrypto.CreateDecryptor(Key, IV), CryptoStreamMode.Read); MemoryStream m = new MemoryStream(); int input=0; while(input != -1) { input = CryptStream.ReadByte(); if (input == -1) { break; } m.WriteByte(Convert.ToByte(input)); m.Flush(); } Stream fs = File.Open(@"tmp.str", FileMode.OpenOrCreate, FileAccess.Write, FileShare.Read); m.WriteTo(fs); m.Flush(); m.Close(); fs.Close(); Stream ms = File.Open(@"tmp.str", FileMode.Open, FileAccess.Read, FileShare.Read); BinaryFormatter bf = new BinaryFormatter(); mySpan = (Zeitspanne)bf.Deserialize(ms); jetzt = DateTime.Now.Ticks; if((mySpan.s <= jetzt) & (jetzt <= mySpan.e)) { this.Visible=true; } else { Response.Redirect("fehler.aspx"); } ms.Close(); s.Close(); CryptStream.Close();
|
|
Verwandte Artikel |
|
Verlinkte
Dokumente |
|
|
|
|
|