webForumDet fria alternativet

Kryptera cookies?

ASPur ASP

14 svar · 579 visningar · startad av Jesper T

Jesper TMedlem sedan nov. 20017 144 inlägg
#1

Om man sparar lite "känslig information" i cookies kan det då vara idé att kryptera innehållet i kakan?
Låt säga att jag spar behörighetsnivåer i kakan.

1=alla behörigheter
...
5=få behörigheter

Då borde man ju kunna gå in i kakan och ändra sin behörighetsnivå och det är ju mindre bra, och därav min fråga.

:)

OveRRidEMedlem sedan feb. 200112 078 inlägg
#2

Därför lagrar man inte sådan information i cookies, utan i sessions.

Om du mot all förmodan nu måste ha behörighetsnivå i cookien, får du använda en ordentlig krypteringsalgoritm och en nyckel som bara finns på servern (eller i dess minne) för att dekryptera innehållet.

Jag skulle dock inte lagra sådan information i en cookies, speciellt inte om den styr rättigheterna i systemet. Det känns som nyckeln under dörrmattan ungefär.

Jesper TMedlem sedan nov. 20017 144 inlägg
#3

Ha, ha... :) Ok, ja du ser.
Det finns ingen möjlighet att ändra sessionsinnehållet då?

MeleaMedlem sedan juli 20033 147 inlägg
#4

För utomstående, nej. :)

tydalMedlem sedan juni 20034 013 inlägg
#5

I ditt fall behöver du dock inte kryptera eftersom du inte behöver dölja behörighetsnivån för användaren (väl?). Allt du vill är ju att användaren inte ska kunna ändra på den. Till det använder du digitala signaturer. En vanligt förekommande algoritm för att skapa signaturer är MD5.

Du kan testa den på: http://www.tydal.nu/se/tools/

Det går till så att du har en hemlig kod på servern som du lägger till behörighetsnivån, sedan skapar du en MD5-signatur av det och skickar signaturen tillsammans med behörighetsnivån till användaren. För att kolla att den inte blivit ändrad tar du behörighetsnivån användaren säger sig ha, lägger till den hemliga kod och räknar ut signaturen som du sedan jämför med den användaren skickar över. Stämmer det så vet du att användaren inte har ändrat behörighetsnivån. Skulle han ändra behörighetsnivån så vet han inte hur han ska räkna ut den nya signaturen eftersom han inte vet din hemliga kod.

Exempel: din hemliga kod är: hemlig123
Behörighetsnivån är: 2

Vi skapar en signatur för: 2hemlig123
Signatur: 3f4194a5f81ce82eeb8aaa1ea4f3eb3c

Vi sätter följande i en cookie hos användaren:
Level=2
MD5=3f4194a5f81ce82eeb8aaa1ea4f3eb3c

När användaren besöker nästa sida har han provat att ändra behörighetsnivån:
Level=4
MD5=3f4194a5f81ce82eeb8aaa1ea4f3eb3c

Vi tar fyran och lägger till hemliga koden:
4hemlig123 och så kör vi md5:
e112e6d10425f61ed0dc0dc4d00195cb

Inte en siffra rätt! Personen har ändrat behörighetsnivån. Skicka honom/henne till inloggningssidan igen.

Jesper TMedlem sedan nov. 20017 144 inlägg
#6

Tack för en bra förklaring, men... om jag lägger in behörighetsnivån direkt i en session, så slipper jag väl md5-signaturer och annat, eller?

fredrikMedlem sedan dec. 19991 072 inlägg
#7

Det finns ingen möjlighet att ändra sessionsinnehållet då?

Om du inte har säkrat upp din kod för sk. "Cross-Site Scripting" så kan en utomstående inte ändra värdet i någon annans session, men däremot "stjäla" någon annans session så att den plötsligt blir både inloggad och har samma rättigheter m.m. som den ursprunlige användaren.

Istället för att som i Tydals exempel använda en hemlig nyckel för hela applikationen skulle jag fördra att lägga en nyckel/användare.
Vi tänker oss annars 2 personer som finns i systemet.

Alice har behörighetsnivå 1
Bob har behörighetsnivå 2

De båda är kompisar och ska försöka får Alice att bli Nivå 2.

Genom en "Brute Force" får de fram att Alice hash är:
1hemlig123

Genom att nu hasha strängen:
2hemlig123 vet de nu vilket värde de ska ange för att uppgradera Alice till nivå 2 med.

Om däremot den hemliga strängen är unik/användare spelar det ingen roll om de forcerar fram nycklen "hemlig123" eftersom den bara gäller för "Bob", nycklen för "Alice" hash kanske istället är "123hemlig" vilket då ger ett helt annat resultat.

Att spara känsliga värden i cookies är enligt min mening aldrig bra.

Läs gärna mer om olika tekniker gällande webbsäkerhet på:
http://www.swesecure.com/?ID=dc6ea60a-12ae-4e7e-9e9c-59489ccafa90&CP=

tydalMedlem sedan juni 20034 013 inlägg
#8

Ja, sessioner sparas på webbservern tillsammans med ett unikt id-nummer för varje användare som sparas i en cookie.

tydalMedlem sedan juni 20034 013 inlägg
#9

fredrik skrev:

Genom en "Brute Force" får de fram att Alice hash är: 1hemlig123

Nej, det får de inte. MD5 är inte kryptering, så MD5 kan inte dekrypteras överhuvudtaget. Inte ens med brute force. Du förväxlar det med när MD5 används för lösenordsverifiering. Där behöver du aldrig få reda på vad det ursprunliga lösenordet var, för det räcker att det du skriver hashas till samma resultat.

I det här fallet med signering skulle du kunna få fram att "gfd0rj4" ger den MD5-hash som du har fått i cookien, men vad hjälper det dig? Du har fortfarande inte fått reda på den hemliga koden och kan därmed inte skapa den nya hashen för den önskade behörighetsnivån.

QimenMedlem sedan juni 20015 009 inlägg
#10

Intressanta inlägg av tydal och fredrik! :)

fredrikMedlem sedan dec. 19991 072 inlägg
#11

I det här fallet med signering

Exakt vad menar du med "Signering" i detta fallet?

Om Orginalvärdet är "2hemlig123" så blir ju hashen:
3f4194a5f81ce82eeb8aaa1ea4f3eb3c

Vilket skulle leda till att vi genom en "Brute Force" kan få fram att just värdet blir "2hemlig123".

Har vi då två användare där vi "Brute Force".ar bådas hash-värden kommer vi se vilken del som är "saltet"(hemliga nycklen) och på så vis kan vi ändra den egna behörigheten.

tydalMedlem sedan juni 20034 013 inlägg
#12

fredrik skrev:

Exakt vad menar du med "Signering" i detta fallet?

MD i MD5 står för Message Digest. Vad det handlar om är att man tar en text och buntar ihop den för att få fram en kontrollsiffra. Kontrollsiffran består av 128 bitar. För texter kortare än 128 bitar (16 tecken) kan du ju få fram vilken text det var med brute force (förutsatt att du vet att den är kortare), men för längre går inte det i och med att du får fler träffar.

fredrik skrev:

Om Orginalvärdet är "2hemlig123" så blir ju hashen:
3f4194a5f81ce82eeb8aaa1ea4f3eb3c

Det var bara ett exempel. I själva verket är koden längre än 16 tecken.

fredrik skrev:

Har vi då två användare där vi "Brute Force".ar bådas hash-värden kommer vi se vilken del som är "saltet"(hemliga nycklen) och på så vis kan vi ändra den egna behörigheten.

Försök gärna om du vill:

Nivå: 72
MD5: d750c0b79b73f4d39d388a1a56fe84fa
Nivå: 43
MD5: d73a6652d7f7dec2cfe519fe5bdde566

BrimbaMedlem sedan dec. 19995 875 inlägg
#13

tydal skrev:

Det var bara ett exempel. I själva verket är koden längre än 16 tecken.

Det är dock en viktig detalj som du inte nämnde i inläggen ovanför. Som jag tolkar fredrik så poängterar han vikten av att när man hashar med md5 så måste man tänka på vad det är man hashar och han påtalade vikten av att hashen är användarunik.
Varför den skall vara användarunik är att om en person kommer över en annan persons kaka så spelar det ju ingen som helst roll hur lång text du har hashat med eftersom den andra användaren bara kan klippa in den och använda den på sin dator med sin användare.

Om man istället gör varje hash användarunik med en nyckel som kan se ut såhär

LEVEL+HEMLIGT SALT+ANVÄNDARID

exempelvis
5+sdjfoij2890892jdzmxIXDMmSO")#K!=)+489213

det gör att den endast kan användas av den som har det användaridt.

fredrikMedlem sedan dec. 19991 072 inlägg
#14

Det var bara ett exempel.

Ok, ja, det framgick inte, så det är viktigt att poängtera att nycklen ska vara längre, annars fungerar ju faktiskt en "Brute Force".

tydalMedlem sedan juni 20034 013 inlägg
#15

Brimba skrev:

Varför den skall vara användarunik är att om en person kommer över en annan persons kaka så spelar det ju ingen som helst roll hur lång text du har hashat med eftersom den andra användaren bara kan klippa in den och använda den på sin dator med sin användare.

Kommer man över en annan persons cookie kan man ändå logga in som den personen, så då spelar det ju ingen roll. I det här fallet handlade det om att förhindra en användare från att ändra ett värde, och då kan man signera det. Visst kan man lägga på användar-id och klockslag, men det blir ju ändå bara teoretiskt eftersom man i själva verket lagrar behörighetsnivån på servern.

Visst borde jag nämna att det är viktigt med en lång hemlig kod, men jag tänkte att det är underförstått eftersom man inte behöver minnas den.

Fast alla kanske inte har läst det jag skrivit tidigare, så jag tar och klistrar in det igen:

"Nu kommer vi till steg tre, och då blir det lite värre, för vi kan ju inte bara använda en variabel för att tala om att personen är inloggad, för användaren kan nämligen själv välja vilka variabler som ska skickas mellan sidor och vad de ska innehålla. Det har man ingen kontroll över som webbplatsinnehavare.

Om du bara gjorde så att efter att Alice hade loggat in sparade värdet "Alice är inloggad" i en cookie (som det heter) så skulle hon kunna ändra det till "Bob är inloggad" utan att du märkte något och vips skulle hon komma åt Bobs saker (om du nu har någon uppdelning). Men vad värre är, om Mallory kommer och vill logga in så skulle hon kunna skicka "Alice är inloggad" till din webbplats och bli inloggad utan att ange något lösenord.

Därför måste vi använda oss av lite kryptering, närmare bestämt en hash-funktion som är inbyggd i php och heter md5.

MD5 är som en svart låda. Du stoppar in något i den och så får du något annat tillbaka, men du vet inte hur det gick till. (Fast om du skulle vilja veta så finns faktiskt formeln beskriven här: http://www.faqs.org/rfcs/rfc1321.html )

När man skickar något till md5 så får man alltid 32 tecken tillbaka oavsett hur många tecken man skickade. Och dessa 32 tecken ska inte på något vis påminna om det du skickar in, för det ska inte gå att gå bakvägen och få reda på vad man skickade in, utan md5 funkar bara åt ett håll. Men du får alltid samma resultat med md5 om du skickar in samma sak, och det är det som är finessen; det är så man kan kontrollera att det stämmer.

När nu Alice loggar in så sätter du återigen värdet "Alice är inloggad", men du kör också "Alice är inloggad" genom md5 och får: 605d4982c9b4849ad73522f7ddc75b98 och sparar även det värdet i en cookie.

När Alice sedan försöker gå in på någon sida skickar hennes dator över cookien "Alice är inloggad" och 605d4982c9b4849ad73522f7ddc75b98 och du kör md5 på "Alice är inloggad" och jämför med de 32 tecken hon skickade med. Stämmer det så vet du att hon inte har ändrat på inloggningen. För om hon nu skulle ändra till "Bob är inloggad" så skulle det bli dc011293eefc34a6c91727f09daa2184 när du kör md5 på det, och då stämmer det inte med de 32 tecken hon fick av dig tidigare.

Fast nu råkar ju Alice vara lite intelligent. Hon har nämligen också tillgång till php och därmed md5-funktionen. Så, hon tar helt enkelt och kör "Bob är inloggad" genom md5 och kan därmed skicka de rätta 32 tecknen till dig så du tror att det verkligen är Bob som är inloggad.

Ja, där har vi ännu ett problem vi måste lösa, och det går att lösa med hjälp av en hemlig kod. Vi antar för exemplets skull att den hemliga koden är "hemlig_kod". Innan vi nu skickar "Alice är inloggad" till md5 så sätter vi ihop det med "hemlig_kod" så vi får: "Alice är inloggadhemlig_kod". När vi skickar det genom md5 får vi: 71d2e5028c2b48d68c33332e51788d10 och dessa 32 tecken skickar vi till Alice tillsammans med "Alice är inloggad", men den hemliga koden får hon absolut inte.

Nu kan inte Alice ändra "Alice är inloggad", för trots att hon har tillgång till md5 så kan hon inte räkna ut de 32 tecknena, för till det behövs den hemliga koden.

Men det finns fortfarande ett problem. Mallory hälsar nämligen på hos Alice en dag och hittar de 32 tecknena från din sida som står för "Alice är inloggad". Med hjälp av dessa kan hon nu logga in som Alice från sin egen dator.

För att lösa det problemet får man tillsammans med den hemliga koden också baka in ett klockslag, så att de 32 tecknen bara gäller exempelvis en timme, sedan måste man logga in på nytt. Då har Mallory ingen nytta av koden eftersom den ändå är värdelös innan hon hunnit komma hem.

Men, i princip så här (vid godkänd inloggning):

$hemligKod = "hemlig";
$tid = time() + 3600;
$hash = md5($_POST["username"] . $tid . $hemligKod);
SetCookie("username", $_POST["username"], time() + 3600, "/", "", 0);
SetCookie("tid", $tid, time() + 3600, "/", "", 0);
SetCookie("hash", $hash, time() + 3600, "/", "", 0);

Sedan, på varje sida som kräver inloggning för att ses gör du så här:

$hemligKod = "hemlig";
if (($tid < time()) || md5($username . $tid . $hemligKod) != $hash)
{
header("Location: login.html");
exit;
// Ej godkänd inloggning.
}
// Här kommer den riktiga sidan.

De här sakerna som jag berättar för dig nu är som du förstår väldigt viktiga när man jobbar med inloggning, men tyvärr känner inte alla som jobbar med sånt till dem. (Exempelvis har Hotmail missat på en del punkter vilket gör att man kan komma åt andras konton.) Så det är därför jag talar om ganska mycket, så att du förhoppningsvis åtminstone ska komma ihåg att det är väldigt mycket man måste tänka på för att få det säkert."

137 ms totalt · 3 externa anrop · v20260731065814-full.29ac60f6
0 ms — hämta forumlista (cache)
0 ms — hämta statistik (cache)
132 ms — hämta tråd, inlägg och bilagor (db)