Kritisk terminologi som utvecklare måste känna till

By rik

I en värld där data blir alltmer central, har säker hantering av användardata blivit viktigare än någonsin tidigare.

Vi utvecklare har redan en utmanande uppgift framför oss. Vi måste hantera komplexa system med många potentiella felkällor, samtidigt som vi tolkar och omvandlar kundernas önskemål till användarvänliga gränssnitt och fungerande backends. Nu läggs dessutom ett alltmer väsentligt krav till: datasäkerhet. Det är av goda skäl. Som kunder reagerar vi starkt negativt om vår data missbrukas. Därför är det bara rättvist att ge våra användare en säker och positiv upplevelse. Dessutom ställer både regeringar och företag krav på efterlevnad.

Datasäkerhet som en Gemensam Ansträngning

Det som komplicerar säkerhetsarbetet är att det har flera lager och lätt blir ett ”allas ansvar är ingens ansvar”. I ett modernt molnteam har flera team direkt kontroll över dataflödet: utvecklare, databasadministratörer, systemadministratörer (DevOps-team), privilegierade backoffice-användare och så vidare. Det är lätt för dessa roller att se datasäkerhet som någon annans problem. Verkligheten är dock att de alla har sina egna ansvarsområden. En databasadministratör kan inte styra säkerheten på applikationssidan, en DevOps-person kan inte göra något åt backoffice-åtkomsten och så vidare.

Utvecklarens Roll i Datasäkerhet

Utvecklare har den största ytan som berör data. De skapar varje del av applikationen, kopplar till olika backend-tjänster, hanterar åtkomsttoken och har full tillgång till databasklustret för läsning och skrivning. Applikationerna de skriver har obehindrad tillgång till alla systemets delar. Till exempel kan en produktions-Django-applikation potentiellt tömma eller radera hela en S3-samling från de senaste tio åren. Därför är risken för slarv eller förbiseende av säkerheten störst på källkodsnivå, vilket gör detta till utvecklarens direkta ansvar.

Datasäkerhet är ett oändligt ämne, och jag kommer inte ens att skrapa på ytan i det här inlägget. Jag vill dock gå igenom den grundläggande terminologi som utvecklare måste känna till för att skydda sina applikationer. Tänk på det som en introduktionskurs i applikationsdatasäkerhet.

Låt oss börja!

Hashing

En rigorös definition finns alltid på Wikipedia, men i grunden är hashing processen att omvandla data till en annan, oläsbar form. Ett exempel är den välkända (och osäkra) Base64-kodningen, där strängen ”Är min hemlighet säker hos dig?” kan ”hashas” till ”SXMgbXkgc2VjcmV0IHNhZmUgd2l0aCB5b3U/”. Om du till exempel skulle skriva din dagbok i Base64-format, skulle din familj inte kunna läsa dina hemligheter (förutsatt att de inte kan avkoda Base64)!

Denna idé om att förvränga data används för att lagra lösenord, kreditkortsnummer etc. i webbapplikationer (och bör egentligen användas i alla typer av applikationer). Tanken är att i händelse av en dataintrång, ska angriparen inte kunna använda lösenord, kreditkortsnummer etc. för att orsaka skada. Mycket avancerade algoritmer används för denna hashing; Base64 är otillräckligt och skulle brytas omedelbart av en angripare.

Lösenordshashing använder en kryptografisk teknik som kallas envägshashing. Det innebär att även om det är möjligt att kryptera data, är det inte möjligt att avkoda den. Hur vet då applikationen att det är rätt lösenord när du loggar in? Jo, den använder samma hashprocess och jämför den kodade formen av det du angav som lösenord med den lagrade kodade formen. Om de matchar, får du logga in!

När vi ändå pratar om hashing, så är detta intressant. Om du någonsin laddar ner programvara eller filer från internet, kan du ha blivit ombedd att verifiera filerna innan du använder dem. Om du exempelvis vill ladda ner en Ubuntu Linux ISO, kommer nedladdningssidan att erbjuda ett alternativ för att verifiera din nedladdning; om du klickar på det öppnas en popup:

Popup-fönstret instruerar dig att köra ett kommando, vilket i grunden hash:ar hela filen och jämför resultatet med den hashsträng som visas på nedladdningssidan: 5fdebc435ded46ae99136ca875afc6f05bde217be7dd018e18419246b5d. Denna konvertering utförs med hjälp av SHA256-algoritmen, vilket du kan se i slutet av kommandot: shasum -a 256 –check.

Tanken är att om hashen som din kontroll genererar är annorlunda, betyder det att någon har manipulerat din nedladdning och försett dig med en komprometterad fil.

Vanliga algoritmer inom lösenordshashing är MD5 (osäker och föråldrad), SHA-1 och SHA-2 (en familj av algoritmer där SHA-256 och SHA-512 ingår), SCRYPT, BCRYPT etc.

Saltning

All säkerhet är en katt-och-råtta-lek. Tjuven lär sig det nuvarande systemet och hittar en ny svaghet, vilket uppmärksammas, och låstillverkarna förbättrar sitt skydd, och så vidare. Kryptografi är inget undantag. Även om det har blivit omöjligt att omvandla hash till lösenord, har angripare över tid utvecklat sofistikerade tekniker som kombinerar smarta gissningar med beräkningskraft. Som ett resultat kan de i många fall gissa det rätta lösenordet med hjälp av bara hashen.

”Herr. Rumpelstiltskin, antar jag?!”

Saltning är en teknik som utvecklades som svar på detta. Det innebär att hashberäkningen av ett lösenord (eller annan data) utförs baserat på en kombination av två saker: själva datan, samt en ny slumpmässig sträng som angriparen inte kan gissa. Om vi vill hasha lösenordet superman009 med saltning, skulle vi först välja en slumpmässig sträng som ”salt”, till exempel, bCQC6Z2LlbAsqj77 och sedan utföra hashberäkningen på superman009-bCQC6Z2LlbAsqj77. Den resulterande hashen kommer att avvika från de vanliga strukturerna som algoritmen producerar, vilket avsevärt minskar risken för smart omvänd teknik eller gissningar.

Både hashing och saltning är otroligt komplexa områden som ständigt utvecklas. Som applikationsutvecklare ska vi aldrig hantera dem direkt. Det är dock viktigt att vi känner till dessa tekniker för att kunna fatta bättre beslut. Om du till exempel underhåller ett gammalt PHP-ramverk och märker att det använder MD5-hashar för lösenord, vet du att det är dags att införa ett annat lösenordsbibliotek för hantering av användarkonton.

Nycklar

Termen ”nycklar” används ofta i samband med kryptering. Hittills har vi pratat om lösenordshashing eller envägskryptering, där vi oåterkalleligt konverterar data och förstör den ursprungliga formen. Det är olämpligt i många praktiska situationer – ett dokument som är skrivet och skickat med e-post på ett sätt som gör att det aldrig kan läsas är inte till någon nytta. Vi behöver kunna kryptera data så att informationen är läsbar för avsändaren och mottagaren, men oläsbar under överföring eller lagring.

Det är här ”nycklar” kommer in i bilden inom kryptografi. Det är precis vad det låter som: nyckeln till ett lås. Den som äger informationen förvränger den med hjälp av en hemlighet som kallas nyckel. Om inte mottagaren/angriparen har denna nyckel är det omöjligt att avkoda data, oavsett hur avancerade deras algoritmer är.

Rotera nycklar

Även om nycklar möjliggör kryptering och säkerhet, har de samma risker som lösenord. När någon väl har fått tag på en nyckel är hela spelet förlorat. Tänk dig ett scenario där någon hackar en del av en tjänst som GitHub (även om det bara är under några sekunder) och får tag på 20 år gammal kod. Inuti koden hittar de de kryptografiska nycklarna som används för att kryptera företagets data (det är en dålig praxis att lagra nycklar tillsammans med källkod, men det händer oftare än man tror!). Om företaget inte har ansträngt sig att byta nycklar (precis som lösenord), kan samma nyckel användas för att ställa till med stor skada.

Därför har man infört metoden att byta nycklar regelbundet. Detta kallas nyckelrotation, och om du använder en molnleverantör av hög kvalitet bör det vara tillgängligt som en automatiserad tjänst.

Bildkälla: AWS

Till exempel har AWS en dedikerad tjänst för detta som kallas AWS Key Management Service (KMS). En automatiserad tjänst besparar dig besväret med att byta och distribuera nycklar mellan alla servrar och är en självklarhet för stora distributioner idag.

Kryptografi med Offentliga Nycklar

Om all tidigare diskussion om kryptering och nycklar låter komplicerad, så har du helt rätt. Att förvara och överföra nycklar på ett säkert sätt så att endast mottagaren kan se informationen medför logistiska problem som skulle ha hindrat dagens säkra kommunikation från att utvecklas. Tack vare kryptografi med offentliga nycklar kan vi tryggt kommunicera och handla online.

Denna typ av kryptografi var ett stort matematiskt genombrott och är den enda anledningen till att internet inte har kollapsat under rädsla och misstro. Algoritmens detaljer är invecklade och matematiskt avancerade, så jag kommer bara att förklara det konceptuellt här.

Bildkälla: The Electronic Frontier Foundation

Kryptografi med offentliga nycklar bygger på användningen av två nycklar för att bearbeta information. En nyckel kallas privat nyckel och ska förbli privat hos dig och aldrig delas med någon. Den andra kallas offentlig nyckel (därav namnet på metoden) och är avsedd att offentliggöras. Om jag skickar data till dig, måste jag först få din offentliga nyckel och kryptera datan och skicka den till dig. Du kan sedan avkoda datan med din privata nyckel i kombination med din offentliga nyckel. Så länge du inte av misstag avslöjar din privata nyckel, kan jag skicka krypterad data till dig som bara du kan öppna.

Det fina med systemet är att jag inte behöver känna till din privata nyckel, och alla som fångar upp meddelandet kan inte läsa det, även om de har din offentliga nyckel. Om du undrar hur detta är möjligt, är det korta och icke-tekniska svaret att det beror på egenskaperna hos multiplikation av primtal:

Det är svårt för datorer att faktorisera stora primtal. Så om den ursprungliga nyckeln är mycket stor, kan du vara säker på att meddelandet inte kan avkodas, inte ens om tusentals år.

Transport Layer Security (TLS)

Nu vet du hur kryptografi med offentliga nycklar fungerar. Denna mekanism (att använda mottagarens offentliga nyckel för att kryptera data) ligger bakom all popularitet för HTTPS och är det som får Chrome att säga ”Den här webbplatsen är säker”. Det som händer är att servern och webbläsaren krypterar HTTP-trafik (tänk på att webbsidor är långa textsträngar som webbläsare kan tolka) med varandras offentliga nycklar, vilket resulterar i Secure HTTP (HTTPS).

Bildkälla: Mozilla

Det är intressant att krypteringen inte sker på transportlagret som sådant; OSI-modellen nämner ingenting om kryptering av data. Datan krypteras av applikationen (i detta fall webbläsaren) innan den överlämnas till transportlagret, som sedan levererar den till destinationen där den dekrypteras. Processen involverar dock transportlagret, och resultatet blir en säker transport av data. Därför har den lösa termen ”transport” layer security fastnat.

Du kan ibland stöta på termen Secure Socket Layer (SSL). Det är samma koncept som TLS, men SSL är en äldre teknik som nu ersätts av TLS.

Full Disk Encryption

Ibland är säkerhetsbehoven så stora att inget får lämnas åt slumpen. Till exempel kan statliga servrar, som lagrar all biometrisk data i ett land, inte drivas som vanliga applikationsservrar eftersom risken är för hög. För dessa behov är det inte tillräckligt att data endast krypteras under överföring; den måste också krypteras när den lagras. Därför används fullständig diskkryptering för att kryptera hela hårddisken, för att säkerställa att data är säkra även om man fysiskt kommer åt disken.

Det är viktigt att notera att fullständig diskkryptering måste ske på hårdvarunivå. Om vi krypterar hela disken, krypteras även operativsystemet och kan inte köras när maskinen startas. Hårdvaran måste förstå att diskinnehållet är krypterat och måste utföra avkodning i farten när den skickar begärda diskblock till operativsystemet. På grund av detta extra arbete leder fullständig diskkryptering till långsammare läsning/skrivning, vilket utvecklarna av sådana system måste vara medvetna om.

End-to-end-kryptering

Med alla integritets- och säkerhetsrelaterade problem för stora sociala nätverk nuförtiden, är alla medvetna om termen ”end-to-end-kryptering”, även om de inte själva skapar eller underhåller applikationer.

Vi har redan sett hur fullständig diskkryptering är den ultimata skyddsstrategin, men den är inte praktisk för vanliga användare. Tänk dig att Facebook vill att den telefondata som den genererar och lagrar i din telefon ska vara säker, men de har inte behörighet att kryptera hela telefonen och stänga ute allt annat.

Därför har dessa företag infört end-to-end-kryptering. Det innebär att data krypteras när den skapas, lagras eller överförs av applikationen. Med andra ord, även när informationen når mottagaren är den helt krypterad och endast tillgänglig för mottagarens telefon.

Bildkälla: Google

Observera att end-to-end-kryptering (E2E) inte har samma matematiska garantier som kryptografi med offentliga nycklar. Det är bara standardkryptering där nyckeln lagras hos företaget, och dina meddelanden är lika säkra som företaget bestämmer.

Slutsats 👩‍🏫

Du har förmodligen hört talas om de flesta av dessa termer. Kanske till och med alla. Om det är fallet, uppmuntrar jag dig att granska din förståelse av dessa begrepp och att utvärdera hur seriöst du tar dem. Kom ihåg att datasäkerhet i applikationer är ett krig som du måste vinna varje gång (inte bara en gång), eftersom även ett enda brott kan förstöra hela branscher, karriärer och till och med liv!