Laden...

Key Generator

Erstellt von Björn vor 15 Jahren Letzter Beitrag vor 9 Jahren 27.422 Views
B
Björn Themenstarter:in
142 Beiträge seit 2007
vor 15 Jahren
Key Generator

Hallo zusammen,

ich habe zu Übungszwecke mal einen kleinen Keygenerator geschrieben, welcher euch Keys erstellt und auch überprüft. Ich stelle ihn hier zur Verfügung, vielleicht kann ihn ja jemand gebrauchen oder hat noch ein paar Verbesserungsvorschläge 🙂

Beschreibung:

Ein simpler Keygenerator, welcher Schlüssel erstellt überprüft.
Je nach Einstellung hat der Schlüssel zum Beispiel so ein aussehen:

"cfhSL-NNnNS-dPyjn-Z6vlG-1SMbV"

Folgende Einstellungen könnt ihr machen:


        /// <summary>
        /// Legt die Anzahl der Schlüsselelemente fest. Muss größer oder gleich 2 sein.
        /// </summary>
        public int numberOfKeyElements
        {
              // 5
        }

        /// <summary>
        /// Setzt die Anzahl der Zeichen pro Schlüsselelement oder gibt diese zurück! Muss größer oder gleich 3 sein!
        /// </summary>
        public int KeyLengthPE
        {
              // 5
        }


        /// <summary>
        /// Setzt oder gibt das Trennzeichen für die Schlüsselelemente zurück. Das Trennzeichen darf nicht in den verwendbaren Zeichen für den Schlüssel vorkommen!
        /// </summary>
        public char KeySeperator
        {
              // -
        }

        /// <summary>
        ///  Setzt oder gibt den Schlüsseltypen zurück.
        /// </summary>
        public KeyTyp Keytyp
        {
              // KeyTyp.AlphaNumeric (also Zahlen und Buchstaben String)
              // Möglich sind noch Numeric (nur Zahlenstring) und Alpha (nur Buchstabenstring)
        }

        /// <summary>
        /// Legt die validen Buchstaben für den Schlüssel fest.
        /// </summary>
        public string ValidAlphaKeys
        {
              // ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
        }

        /// <summary>
        /// Legt die validen numerischen Zeichen für den Schlüssel fest.
        /// </summary>
        public string ValidNumericKeys
        {
             // 0123456789
        }

        /// <summary>
        /// Legt fest oder gibt an, ob die Groß- / Kleinschreibung beachtet wird.
        /// </summary>
        public bool UseCaseSensitive
        {
             // true
        }

Dies sind die Einstellungsmöglichkeiten. Die Kommentare geben die Standardwerte wieder. Nun noch kurz zu den Erstellen / Prüfen funktionen.

        /// <summary>
        /// Erstellt einen Schlüssel.
        /// </summary>
        /// <returns>Gibt einen Schlüssel als String zurück, getrennt durch den Seperator.</returns>
        public string GenerateKey()
        {
        }

        /// <summary>
        /// Erstellt einen Schlüssel.
        /// </summary>
        /// <returns>Gibt einen Schlüssel als Array zurück.</returns>
        public string[] GenerateKeyAr()
        {
        }

        /// <summary>
        /// Prüft einen Schlüssel, welcher anhand des "KeySeperator" aufgesplittet wird.
        /// </summary>
        /// <param name="Key">Der Schlüssel als kompletter String</param>
        /// <returns>true wenn der Schlüssel valid ist, false wenn nicht.</returns>
        public bool CheckKey(string Key)
        {
        }

        /// <summary>
        /// Prüft einen Schlüssel anhand der einzelnen Elemente.
        /// </summary>
        /// <param name="KeyElements">Array mit den einzelnen Schlüsselelementen</param>
        /// <returns>true wenn der Schlüssel valid ist, false wenn nicht.</returns>
        public bool CheckKey(string[] KeyElements)
        {
        }

Denke die Erklärungen sind selbst sprechend!

Im Anhang findet ihr eine kompilierte DLL sowie den Source Code.
Wünsche viel Spaß damit und ich dankbar für eure Kommentare 🙂

Ach ja noch kurz, der "Algorithmus" ist was selbst ausgedachtes und sicherlich nichts wirklich sicheres aber ich denke für kleinere Dinge sollte er ausreichen.

MfG Björn

Schlagwörter: Key, Gen, Keygenerator, Generator, Schlüssel, Serial

I
1.739 Beiträge seit 2005
vor 15 Jahren

Frage:
Was wäre denn der Anwendungszweck, z.B. im Vergleich zu einer GUID?

49.485 Beiträge seit 2005
vor 15 Jahren

Hallo ikaros,

Was wäre denn der Anwendungszweck, z.B. im Vergleich zu einer GUID?

z.B. CD-Keys oder Keys für Shareware. Der Vorteil gegenüber einer GUID ist, dass man Länge und Aufbau des Keys an die eigenen Vorstellungen anpassen kann.

herbivore

I
1.739 Beiträge seit 2005
vor 15 Jahren

Danke,
daran hatte ich nicht gedacht.

415 Beiträge seit 2006
vor 15 Jahren

Also ich hab mir das ganze mal eben angesehen und ausprobiert.
Jedoch krieg ich immer die Meldung, dass der eingegebene Schlüssel nicht richtig ist, obwohl ich mit einem Button den Key erzeuge und in eine TextBox speichere und in mit einem anderen Button prüfe, ob er gültig ist.

Hier mal mein Code, mit dem ich getestet habe:


        private void button2_Click(object sender, EventArgs e)
        {
            KeyGen kg = new KeyGen();
            kg.KeySeperator = '-';
            kg.KeyLengthPE = 5;
            kg.Keytyp = KeyTyp.AlphaNumeric;
            kg.numberOfKeyElements = 4;
            kg.UseCaseSensitive = true;
            MessageBox.Show(kg.CheckKey(textBox1.Text).ToString());
        }

        private void button1_Click(object sender, EventArgs e)
        {
            KeyGen kg1 = new KeyGen();
            kg1.KeySeperator = '-';
            kg1.KeyLengthPE = 5;
            kg1.Keytyp = KeyTyp.AlphaNumeric;
            kg1.numberOfKeyElements = 4;
            kg1.UseCaseSensitive = true;
            textBox1.Text = kg1.GenerateKey();
        }

Mfg Tobi

415 Beiträge seit 2006
vor 15 Jahren

ok, ich hab den Fehler gefunden.
In der Methode "checkKey" muss einfach folgendes abgeändert werden:


            for (int i = 0; i < this.lNumberOfKeyElements; i++)
            {
                if (this.lUseCaseSensitive)
                {
                    // Wenn groß und kleinschreibung nicht beachtet werden soll!
                    KeyElements[i] = KeyElements[i].ToUpper();
                }
                if (this.lKeyElements[i] != KeyElements[i])
                {
                    return false;
                }
            }

zu:


            for (int i = 0; i < this.lNumberOfKeyElements; i++)
            {
                if (this.lUseCaseSensitive)
                {
                    // Wenn groß und kleinschreibung nicht beachtet werden soll!
                    KeyElements[i] = KeyElements[i].ToUpper();
                    this.lKeyElements[i] = this.lKeyElements[i].ToUpper();
                }
                if (this.lKeyElements[i] != KeyElements[i])
                {
                    return false;
                }
            }

Mfg Tobi

888 Beiträge seit 2007
vor 11 Jahren

Der KeyGen funktioniert nicht beim Wechsel von x86 zu x64 oder umgedreht.
(Also auch nicht beim Wechsel von Windows XP zu z.B. W7)

Der Grund dafür ist das string.GetHashCode() unterschiedliche Werte für den gleichen String bei unterschiedlicher Prozessorarchitektur liefert.

Lösungen aus dem Netz:


    /// <summary>
    /// Similar to String.GetHashCode but returns the same as the x86 version of String.GetHashCode for x64 and x86 frameworks.
    /// </summary>
    /// <param name="s"></param>
    /// <returns></returns>
    public static unsafe int GetHashCode32(string s)
    {
        fixed (char* str = s.ToCharArray())
        {
            char* chPtr = str;
            int num = 0x15051505;
            int num2 = num;
            int* numPtr = (int*)chPtr;
            for (int i = s.Length; i > 0; i -= 4)
            {
                num = (((num << 5) + num) + (num >> 0x1b)) ^ numPtr[0];
                if (i <= 2)
                {
                    break;
                }
                num2 = (((num2 << 5) + num2) + (num2 >> 0x1b)) ^ numPtr[1];
                numPtr += 2;
            }
            return (num + (num2 * 0x5d588b65));
        }
    }

oder


/// <summary>
/// http://www.codeproject.com/Articles/34309/Convert-String-to-64bit-Integer
/// Return unique Int64 value for input string
/// </summary>
/// <param name="strText"></param>
/// <returns></returns>
static Int64 GetInt64HashCode(string strText)
{
    Int64 hashCode = 0;
    if (!string.IsNullOrEmpty(strText))
    {
        //Unicode Encode Covering all characterset
          byte[] byteContents = Encoding.Unicode.GetBytes(strText);
        System.Security.Cryptography.SHA256 hash = 
		new System.Security.Cryptography.SHA256CryptoServiceProvider();
        byte[] hashText = hash.ComputeHash(byteContents);
        //32Byte hashText separate
        //hashCodeStart = 0~7  8Byte
        //hashCodeMedium = 8~23  8Byte
        //hashCodeEnd = 24~31  8Byte
        //and Fold
        Int64 hashCodeStart = BitConverter.ToInt64(hashText, 0);
        Int64 hashCodeMedium = BitConverter.ToInt64(hashText, 8);
        Int64 hashCodeEnd = BitConverter.ToInt64(hashText, 24);
        hashCode = hashCodeStart ^ hashCodeMedium ^ hashCodeEnd;
    }
    return (hashCode);
}        

G
308 Beiträge seit 2006
vor 9 Jahren

Hallo,

ich finde diese Klasse echt super.
Allerdings habe ich eine kleine Anregung bzw Frage.

Ich würde gerne einen String mit für die Generierung hinzuziehen.

Als Beispiel den PC-Name.

Ist sowas möglich und wie?

Gruß Simon

49.485 Beiträge seit 2005
vor 9 Jahren

Hallo Grimmbizkit,

es steht dir doch frei, die Methode GenerateKey mit einem String-Parameter auszustatten, den du intern bis an die Stelle(n) weitergibst, wo die Zufallswerte erzeugt werden, um dort den Inhalt des Strings in der von dir gewünschten Weise in das Ergebnis der Erzeugung einfließen zu lassen. Deine Änderungen/Überarbeitungen kannst du dann gerne für die Nachwelt in diesem Thread posten.

herbivore

G
308 Beiträge seit 2006
vor 9 Jahren

Danke herbivore,

aber ich möchte diesen String auch bei CheckKey nutzen, als zusätzliche Kontrolle.

Da finde ich irgendwie nicht den Ansatz.

Gruß Simon

49.485 Beiträge seit 2005
vor 9 Jahren

Hallo Grimmbizkit,

dafür gibt es verschiedene Möglichkeiten.

Du könntest als Seed für die Generierung von Zufallszahlen den Hashcode des Strings (z.B. PC-Name) verwenden (beachte dazu allerdings, was Joetempes bezüglich der Hashberechnung geschrieben hat). Dadurch wäre der Seed deterministisch und ein erneutes Aufrufen von GenerateKey mit dem gleichen String würde dasselbe Ergebnis liefern. Du könntest also in CheckKey, das dafür ebenfalls einen (weiteren) String-Parameter bekommen müsste, einfach nochmal GenerateKey aufrufen und schauen, um das Ergebnis mit dem zu prüfenden String übereinstimmt.

Natürlich kannst du den String auch nur in einen Teil des Keys einfließen lassen und den Rest zufällig wie bisher halten.

Statt Hashcode des Strings als Seed zu verwenden, könntest du auch (mehrfach) die MD5-Summe (o.ä.) berechnen und Teile daraus aus Teile des Keys verwenden. Auch hier wäre die Berechnung deterministisch und würde sich nachträglich prüfen lassen.

Das nur als Anregung. Bei der konkrete Ausgestaltung bist du frei. Und es gibt natürlich noch weitere Möglichkeiten und Varianten.

herbivore

G
308 Beiträge seit 2006
vor 9 Jahren

Morgen Zusammen,

ich habe den PC-Namen einfach mit an die "toShuffle" angefügt.
Gebe ich diesen String auch mit beim CheckKey an ist alles ok.

Nun habe ich aber noch ein kleines Problem.

Ich würde gerne eine Zahl (Lizenzgröße) mit in den Key packen und diesen später auch wieder auslesen. Kann ich überhaupt Werte später wieder auslesen?

Gruß Simon

49.485 Beiträge seit 2005
vor 9 Jahren

Hallo Grimmbizkit,

natürlich kannst du bestimmte Stellen des Keys verwenden, um darin (verschlüsselt aber trotzdem) wieder auslesbare Informationen zu speichern.

Wenn es jedoch nur wenige verschiedene Lizenzgrößen gibt, dann könntest du probieren die Lizenzgröße einfach ebenfalls an toShuffle anhängen. Beim Prüfen gehst du dann einfach alle Möglichkeiten durch, und schaust bei welcher die Prüfung erfolgreich ist. Das klappt natürlich nur dann zuverlässig, wenn alle Zeichen von toShuffle komplett in den Key einfließen.

herbivore