Laden...

Generator für eindeutige Urls (z.B. für ein Account-Aktivierungs-System)

Erstellt von TheBrainiac vor 13 Jahren Letzter Beitrag vor 13 Jahren 5.796 Views
TheBrainiac Themenstarter:in
795 Beiträge seit 2006
vor 13 Jahren
Generator für eindeutige Urls (z.B. für ein Account-Aktivierungs-System)

Beschreibung:

Da ich gerade an einem Account-Aktivierungs-System arbeite, brauche ich sichere und eindeutige Links, die ich per Mail senden kann.

Bisher habe ich immer Guid verwendet, aber angeregt durch diesen Thread generiere ich meine Tickets jetzt selbst.

Hier die Methode samt kleiner Test-Anwendung

using System;
using System.Text;
using System.Security.Cryptography;

public class MyClass
{
	public static void Main()
	{
		Console.WriteLine("Ticket (strong, base64):");
		Console.WriteLine(CreateTicket("TheBrainiac", true, true));
		Console.WriteLine("Ticket (strong, hex):");
		Console.WriteLine(CreateTicket("TheBrainiac", true, false));
		Console.WriteLine("Ticket (weak, base64):");
		Console.WriteLine(CreateTicket("TheBrainiac", false, true));
		Console.WriteLine("Ticket (weak, hex):");
		Console.WriteLine(CreateTicket("TheBrainiac", false, false));
	}
	
	public static string CreateTicket(string customData, bool strong, bool base64) {
		RandomNumberGenerator provider = RNGCryptoServiceProvider.Create();
		
		byte[] randomData = new byte[64];
		provider.GetNonZeroBytes(randomData);
		
		byte[] stringData = Encoding.Default.GetBytes(customData);
		byte[] timeData = BitConverter.GetBytes(DateTime.Now.Ticks);
		
		byte[] allData = new byte[randomData.Length + stringData.Length + timeData.Length];
		Array.Copy(randomData, 0, allData, 0, randomData.Length);
		Array.Copy(stringData, 0, allData, randomData.Length, stringData.Length);
		Array.Copy(timeData, 0, allData, randomData.Length + stringData.Length, timeData.Length);
		
		HashAlgorithm hash = strong ? (HashAlgorithm) SHA512Managed.Create() : (HashAlgorithm) MD5.Create();
		
		byte[] hashData = hash.ComputeHash(allData);
		
		if (base64) {
			return Convert.ToBase64String(hashData).ToUpper();
		} else {
			StringBuilder sb = new StringBuilder();
			
			for (int i = 0; i < hashData.Length; i++) {
				sb.Append(Convert.ToString(hashData[i], 16));
			}
			
			return sb.ToString().ToUpper();
		}
	}
}

Die Ausgabe ist in diesem Fall:

Ticket (strong, base64):
PL1FEQVVI/IRBFUFUQVMHSNQQG+OOJFCSF7IYEV9GHGWC8Y+BXXHIKVEVSHGHHIQHCU/HMI72MXP69OZKMHC+G==
Ticket (strong, hex):
906DCF4321B9F98D2AF6FCF46B3C759DC966FEFFFC6E64B7F42726EC7F9B6AE3551FCF6B25ED2CD4FAE1A6A4FA6CAE1CE26B6B8C3620A053F8C1DEFEA88A
Ticket (weak, base64):
UHBFASXCG2OQ9NZA32+9CG==
Ticket (weak, hex):
4DBB374EBC3BC195CC93AD97A8816D

Gruß, Christian.

Schlagwörter: <Bitte Schlagwörter, unter denen das Snippet über die Suche gefunden werden soll, hier eintragen>

`There are 10 types of people in the world: Those, who think they understand the binary system Those who don't even have heard about it And those who understand "Every base is base 10"`
691 Beiträge seit 2007
vor 13 Jahren

Manche E-Mailprogramme / Webmailer erkennen URLs nicht eindeutig, wenn sie mit einem Sonderzeichen wie "=" enden. D.h. die URl ist anklickbar, aber als target wird nur die Adresse ohne das ende Sonderzeichen genommen. Eventuell solltest sicherstellen, das die letzte Stelle alphanumerisch ist.

mit freundlichen Grüßen,
Tomot

Projekte: www.gesellschaftsspieler-gesucht.de

1.373 Beiträge seit 2004
vor 13 Jahren

Hallo,

Dafür gibt es doch URL-Codierung.

Grüße,
Andre

1.985 Beiträge seit 2004
vor 13 Jahren

Hallo zusammen,

sein String oben mit den Gleichheitszeichen am Ende ist ja schon base64 codiert. Mein Outlook macht daraus beispielsweise folgendes.

Gruß,
Fabian

"Eine wirklich gute Idee erkennt man daran, dass ihre Verwirklichung von vornherein ausgeschlossen erscheint." (Albert Einstein)

Gefangen im magischen Viereck zwischen studieren, schreiben, lehren und Ideen umsetzen…

Blog: www.fabiandeitelhoff.de

2.891 Beiträge seit 2004
vor 13 Jahren

sein String oben mit den Gleichheitszeichen am Ende[...]

Und in deinem Screenshot sind auch noch zwei Slashes enthalten. Mag auch nicht jede HTTP-Engine.
Also statt einfach das generierte Ticket so an den URL anzuhängen, vorher - wie schon gesagt - nochmal in die HttpUtility.UrlEncode-Methode (System.Web) werfen.

49.485 Beiträge seit 2005
vor 13 Jahren

Hallo TheBrainiac,

also ich fände es (auch) besser, wenn CreateTicket direkt eine robuste Url liefern würde, ohne dass der Aufrufer selber noch HttpUtility.UrlEncode o.ä. aufrufen muss. Bei mir persönlich kommt noch hinzu, dass ich UrlEncoded sehr hässlich findet. Vielleicht kannst du einfach die problematischen base64-Zeichen durch sichere ersetzen. Ich glaube irgendwo ist sogar eine base64 Variante spezifiziert, die sich für Urls eignet.

Damit der Benutzer deiner Klasse sich nicht darum kümmern muss, wie du die Url nun genau zusammenbastelst, sollte wäre eine ValidateTicket und/oder eine DecodeTicket-Methode schön ... wollte ich gerade schreiben, aber dann habe ich gesehen, dass du einen Hash berechnest und damit ein zurückrechnen gar nicht mehr möglich ist. In dem Originalvorschlag von VizOne ist von einem Hash nicht die Rede. Ich denke sogar, dass wenn du einen Hash berechnet (insbesondere bei weak), bist du nicht sicherer als mit einer GUID, sondern eher unsicherer.

Dies an dieser Stelle aber bitte nur als Hinweis(e). Bitte hier keine fachliche Diskussion, ob das wirklich so ist. Dass kann bei Bedarf in dem anderen Thread diskutiert werden.

herbivore

3.971 Beiträge seit 2006
vor 13 Jahren

Ich finde Guid ist auch besser. Diese sind im Vergleich schön kurz, haben keinerlei Sonderzeichen und sind definitiv immer eindeutig.

Es gibt 3 Arten von Menschen, die die bis 3 zählen können und die, die es nicht können...

2.891 Beiträge seit 2004
vor 13 Jahren

Guid [...] definitiv immer eindeutig.

Kann man so nicht sagen:

Zitat von: Guid-Struktur (System)
Bei einem solchen Bezeichner ist die Wahrscheinlichkeit der Duplizierung äußerst gering.

1.373 Beiträge seit 2004
vor 13 Jahren

In dem Originalvorschlag von VizOne ist von einem Hash nicht die Rede. Ich denke sogar, dass wenn du einen Hash berechnet (insbesondere bei weak), bist du nicht sicherer als mit einer GUID, sondern eher unsicherer.

Dem stimme ich zu. Warum nicht einfach "richtig" verschlüsseln (z.B. mit Rijndael)?

Grüße,
Andre

TheBrainiac Themenstarter:in
795 Beiträge seit 2006
vor 13 Jahren

Habe das oben genannte schon implementiert (Reversible Ticket mit Encoder / Decoder), bin aber gerade nicht am richtigen PC.

Außerdem habe eine Option für Base36-Encoding hinzugefügt.

Werde es heute abend hochladen.

Gruß, TheBrainiac.

`There are 10 types of people in the world: Those, who think they understand the binary system Those who don't even have heard about it And those who understand "Every base is base 10"`