En viktig del av PHP-utvecklingspraxis är alltid att tänka på att säkerhet inte är något du enkelt kan köpa av hyllan på din lokala, praktiska butik. Att säkerställa säkerheten för dina webbapplikationer är en process som över tiden behöver utvärderas, övervakas och härdas.
Även om användningen av filter och validering av data är en del av säkerhetsprocessen, bör en webbutvecklare vara medveten om att Randomization, Obfuscation och Cryptography i PHP kan göra skillnad i säkerheten för webbapplikationer. Denna handledning guidar dig genom några enkla tekniker för att skapa och använda slumpmässiga eller unika värden inom dina webbapplikationer, ta en titt och tillämpa några generella obfuscationstekniker och se djupare på vetenskapen om kryptologi och det används inom PHP.
Dictionary.com definierar randomisering som:
"-verb: att beställa eller välja på ett slumpmässigt sätt, som i ett prov eller experiment, särskilt för att minska förspänning och störningar som orsakas av irrelevanta variabler, gör slumpmässigt."
Slumpmässig talgenerering bestäms på ett flertal sätt, men beräkningsgeneratorer saknar "sann" slumpmässighet i natur eller elektroniskt brus (den fuzzy, screeching, black and white kanalen på TV). Dessa beräknade värden betraktas som pseudo-slumpmässiga.
PHP ger oss ett antal olika sätt att skapa slumpmässiga värden. Låt oss titta på några av de mer populära funktionerna.
De två funktionerna rand()
och mt_rand ()
är sannolikt de mest använda funktionerna för att generera en uppsättning slumpmässiga tal i PHP. Funktionen rand()
; är en äldre generator, och faller i bruk på grund av mt_rand ()
; vilket är snabbare, mer tillförlitligt och kan hantera ett högre maximalt heltal värde på vissa plattformar. Funktionen str_shuffle ()
gör precis vad du förväntar dig det, blandar det en sträng som skickas till den.
"; skriv ut mt_rand (0, 20); // Utmatar ett slumpmässigt heltal mellan 0 och 20 eko"
"; // Exempel på rand () användning print rand (); // standard echo"
"; skriv ut rand (0, 25); // Utmatar ett slumptalsintervall mellan 0 och 25 eko"
"; // Exempel på str_shuffle-användning $ string = 'abcefghijklmnopqrstuvwxyz'; skriv ut str_shuffle ($ string); // shuffles $ string?>
De rand()
och mt_rand ()
funktionerna båda acceptera två parametrar där $ min
är det lägsta heltalet att börja med, och $ max
vara det största heltalet att sluta med. Funktionen str_shuffle
tar en parameter, en sträng, utmatar en blandad mutation av strängen. Det fungerar på samma sätt som om du shuffling ett kort kort.
Medan mt_rand ();
kommer att spotta ut ett slumpmässigt heltal, och str_shuffle
kommer att blanda en sträng, en funktion som ofta används för att skapa slumpmässiga unika värden är uniqid ()
. Detta genererar en prefixad unik identifierare baserat på aktuell tid i mikrosekunder (via php.net). Användning av denna funktion är användbar för att skapa sessionstoken och till och med formulärnycklar som visas i Säkra dina formulär med formtangenter.
"; skriv ut uniqid (" NETTUTS ", TRUE); // Lägga till ett ytterligare prefix och ställa in more_entropy till TRUE?>
Funktionen uniqid ()
accepterar två parametrar den första lägger till ett prefix till resultaten medan den andra, om den är satt till TRUE, kommer att lägga till ytterligare entropi till slutet av det returnerade värdet.
Det finns ett gazillion exempel på webben som genererar slumpmässiga lösenord, alla gör ett bra jobb åt det. "Men varför" frågar du "skulle jag behöva skapa ett slumpmässigt lösenord?" Tja, svaret är helt enkelt så att du inte behöver lita på slutanvändaren för att försörja sig med ett mindre än säkert lösenord när du går. Att generera slumpmässiga lösenord är mycket användbart vid användarregistreringar, eller när en användare gör en förfrågan eftersom de har glömt sitt lösenord. Genom att göra detta säkerställs ett starkt lösenord i början av en användares upplevelse på din webbplats eller kan skära ner kodlängder när en användare behöver komma åt igen.
Låt oss titta på några exempel: Exempel 1
I det här exemplet blandas en sträng med str_shuffle
och kommer att returnera en sträng inom ett räknat intervall. Så om du ville skapa ett 8 tecken lösenord skulle du skicka 8 till funktionen randompassword eller randompassword (8) från din källkod.
Exempel 2
I jämförelse tar exempel en en statisk sträng och blandar den upp och returnerar den, exempel två lägger till i mer dynamisk smak (mmm smaklig). I exempel två är strängen som blandas inte längre statisk men ändras med varje generation. Medan det första exemplet är säkert i de flesta fall för att skapa ett starkt lösenord, tillåter det andra exemplet oss att se till att stränglängden och tecknen ändras med användning, vilket minskar risken för dubbelarbete.
Förtvinga användningen av starka lösenord i en webbapplikation kommer att hindra användare från att besöka eller anmäla sig till en webbplats. Det är ofta en avvägning mellan att få den trafik du önskar och säkerställa säkerheten för applikationen. Jag föreslår att dina användare kan skapa egna lösenord vid anmälan eller låta dem välja mellan de två.
Saltning lösenord är ett effektivt sätt att öka säkerheten för dina användarkonton, även om en angripare får tillgång till din databas, om den görs rätt. Det kan hävdas att en angripare med tillgång till saltet fortfarande kan få dina uppgifter. Även om detta är sant, kommer tillämpningen av vissa randomiseringstekniker till lagring av lösenord att göra den processen extremt svår, särskilt om lagringen av användarinformation och innehåll är indelad i separata databaser.
Återigen faller detta under "icke-beroende av slutanvändaren att ge sig en enkel säkerhet" åtgärd. Användare brukar använda lösenord som är lätta att komma ihåg, och till och med använda samma lösenord på flera webbplatser (jag vet, rätt !?). Lätt att komma ihåg lösenord är generellt ord som finns i en ordlista och andra typer av värden (ex. 12345, QWERTY). Som utvecklare dömer vi ofta på denna praxis, men vi kan inte förneka att det är precis som sakerna är.
För att en webbapplikation ska kunna använda ett salt i ett lösenord måste applikationen lagra den någonstans. Det rekommenderas inte att använda samma salt över en hel databas med lösenord, men att skapa ett unikt salt per användare. Att generera ett salt för en hel databas minskar faktiskt webbapplikationssäkerheten på ett visst sätt att om en angripare lyckas knäcka hela systemet är brutet, eller om det går förlorat, gör databasen värdelös. Att skapa ett fullvärdigt medlemsregistreringssystem med alla klockor och visselpipor ligger utanför denna handledning, men vi kommer att skapa ett enkelt system för att använda ett exempel. Låt oss titta på att skapa ett salt och tillämpa några randomiseringstekniker:
Här är SQL-tabellen som vi ska använda.
CREATE TABLE IF NOT EXISTS 'users' ('usr_id' int (11) INTE NULL AUTO_INCREMENT, 'usr_name' varchar (24) INTE NULL, 'usr_pass' varchar (32) INTE NULL, 'usr_email' varchar (255) INTE NULL, 'usr_salt' varchar (255) INTE NULL, PRIMÄR KEY ('usr_id')) MOTOR = MyISAM DEFAULT CHARSET = latin1;
Framgång'; annars echo 'Fel
'; ?>
Låt oss gå över PHP-koden. För att hålla sakerna enkla inkluderar vi vår databasfil. Nästa PHP kontrollerar för att se om formuläret HTML har skickats in genom att kontrollera om $ _POST
variablerna är inte tomma. Om de inte är tomma, fortsätter manuset att undvika formulärdata från användaren och förbereder det att införas i databasen. Vi genererar sedan ett enkelt salt med uniqid ()
och mt_rand ()
och lagra den i variabeln $ salt_gen
. För att salta vårt lösenord kombinerar vi $ lösenordet, sedan saltet. Nästa steg, one-way hashing de kombinerade variablerna med md5.
"Men vänta! Du har också lagt till användarnas email till framsidan av lösenordet och saltkombinationen!" Japp! Det gjorde jag för att om en angripare får tillgång till min databas på något sätt och saltet, är det enda sättet angriparen säkert vet att e-postadressen används i lösenordets hackning om de har tillgång till källkoden. Hur slumpmässigt och unikt är en e-postadress?
För att öva resten av PHP-koden av lägger vi in våra variabler i databas tabellen inom respektive fält och ger användaren lite feedback om framgång eller misslyckande. Nu på resten av registreringsfilen, HTML
Här skapar vi en enkel HTML-blankett som samlar in ett användarnamn, ett e-postmeddelande och ett lösenord från en användare. Inget fint här.
Så vi har nu en enkel registreringsblankett, som sätter in en användare i databasen tillsammans med sitt saltade lösenord. Låt oss skapa en inloggningssida som kräver att vi hämtar information från databasen och autentiserar användaren. Först PHP:
Yippie, vi är autentiserade!'; annars echo 'Åh nej, vi är inte autentiserade!
'; annars echo 'Åh nej, vi är inte i databasen!
'; ?>
I grund och botten vad vi gör i login.php-filen tar de inlämnade formulärvariablerna, tar tag i tabellraden som är associerad med användarnamnet och återuppbygger lösenordet från elementen i databasen den skapades med (email, pass, salt) och rehashing dem . Vi kontrollerar sedan databasen igen för användarnamnet OCH det rehashed lösenordsvärdet för att hitta en match och utmatar användaren på framgång eller misslyckande. Slutligen här är HTML:
En enkel men komplex definition av obfuscation är (använd versionen i källan om du vill köra koden):
Som du kan se är den här koden inte avsedd att särskiljas. Det finns inga tydliga variabla namn, det finns inga kommentarer, inget mellanslag, inget inslag, ingen särskild ordning och allt är i en rad. Även om vi inte kan skilja på koden, vet våra maskiner fortfarande vad det är. Det fungerar. Den här raden av kaos helt enkelt echos "Obfusction är en teknik som används för att komplicera koden på ett sådant sätt att jag inte förstår." Ja, jag vet om felen.
Obfuscation har för-och nackdelar. Det är syftet att avskräcka en person från att ta reda på vilken kod som gör ett ögonblick, eller för en tid. Detta är ett plus mot individer med liten eller ingen kunskap om programmeringsspråket. Någon som har en grundläggande förståelse för PHP kan emellertid sprida den ovannämnda koden och räkna ut vad den gör, det kan bara ta lite tid. Det här är ett av felet av förvirring, det är inte en form av kryptering, det är bara ett försök att vara kryptiskt. Obfuscation lägger också normalt till filstorlek. Många gånger kommer du att stöta på obfuscated code i propriatary och skadlig programvara.
Detta är en vanlig fråga. Det finns främst två sätt att förhindra din kod. Först kan du göra det för hand. Att skriva obfuscated kod tar lång tid. Exemplet som använts i den här artikeln tog ett tag att skriva på grund av samma skäl som du använder obfuscation i första hand (brist på struktur, order etc ...), detta resulterade även i några meniala fel som jag inte ens ville jaga och fixa. Det andra sättet att förhindra din kod är att köpa programvara som gör det för dig. Att använda ett program för att obfuscate kod är trivialt och kostar naturligtvis pengar mycket av tiden. Någon programvara som hävdar att obfuscate din kod, krypterar faktiskt och / eller kodar det på ett sådant sätt att det är beroende av ett handslag att fungera. Ofta hittar du program vars leverantör inte ens garanterar att din kod kommer att fungera när den är klar. Även i exemplet använde jag en enkel Base64
funktion för att koda byggandet av manusutmatningen.
Det beror verkligen på din plan. Särskilt om du vill sälja ditt PHP-skript (eller någon programvara) måste du licensera den. Detta kommer att vara ett av de främsta försvaren för att förhindra att programvaran är avsedd att göra vad de vill ha. Ett bra exempel på licensiering kan ses på Envato Marketplace Wiki. Men du kanske vill förvirra någon eller all din kod, oavsett orsak. Men på grund av obfuscations negativ, om du verkligen är orolig för säkerheten för din källkod, kan det vara värt att leta efter kryptering istället.
Wikipedia.com definierar kryptografi som:
"övning och studier av att dölja information."
Kryptografi är en stor sak, om du är medveten om det eller inte. I nästan varje webbapplikation som för närvarande används är det någon närvaro av kryptografi som används (dvs. postklienter och webbplatser). Som utvecklare behöver vi vara informerade och medvetna om de praktiska tillämpningarna av kryptografi inom vår programvara. PHP ger oss några grundläggande och praktiska funktioner som vi kan använda för att kryptera data. I det här avsnittet kommer jag att gå över enstaka hashingalgoritmer, även om jag kommer att beröra lätt på symmetrisk nyckelbaserad kryptering. Det finns mycket mer (dvs Steganography, Asymmetric-Key för att nämna ett par).
Mycket av tiden använder vi enkelriktad hashing som ett sätt att säkert lagra lösenord och kontrollera dataintegriteten för filer. Medan vi gör det här, för att verifiera medlemmar i en webbapplikation har vi använt användarna lösenord, och matchar det mot användarens lagrade hash. Samma teknik gäller för att kontrollera filens integritet.
SHA-1, 2 och 3
SHA-familjen av hashalgoritmer är för närvarande den mest populära, betydligt SHA-1. Även om SHA-1-algoritmen kan ha en svaghet, är den fortfarande i stor utsträckning.
"; echo $ hash2."
"; // Kommer att producera: 42d2f15c3f92d28d7d58776e5d81b800f662cc6c?>
I PHP är SHA-2 uppmanad i en annan respekt, och kräver PHP 5 större än eller lika med 5.1.2. SHA-2 är överlägsen SHA-1 och kan kallas med olika bitstorlekar.
"; echo $ hash_sha384."
"; echo $ hash_sha512."
? "; / * Utgångar repspectively: sha256: 09074adc0d70e15b88494643e29c2836e1ab94a21989691dec594cb0bd742ebc SHA384: 8535470750df54a78701d4bfe0451f9799057a5bc101944a32480d2436e8b95440bce3bcab3f9ce107b0b92d9595ae32 sha512: c2e6dce873a71800b862791e56b480b976bb26cd3136c02da510c3905caa49b7b9e9260549976e1e741cc93e4569a611f2030d3b7104c6c6c2ff9e6c9bf0946a * />
Hashfunktionen heter av hash (algoritm, sträng); I de senaste PHP-versionerna kan hash () -funktionen användas för att anropa alla envägs-hashalgoritm PHP-stöd (dvs md5, sha-1, haval, spöke). Om du vill se en lista över alla registrerade hashingalgoritmer kan du använda:
= 5.1.2 print_r (hash_algos ()); ?>
SHA-3 utvecklas fortfarande och beaktas för standardisering. En tävling för att hitta en bra kandidat för att fungera som den nya säkra hashalgoritmen lanserades av National Institute of Standards and Technology och inlämningsdatum för tävlingen var tidsbegränsat till den 31 oktober 2008. En ganska populär post som heter Skein, har en ledig PHP-modul Du kan ladda ner (även om du måste sammanställa det själv). Skein är utvecklad av några stora namn som finns inom säkerhetsbranschen, som Bruce Schneier, Niels Ferguson och Stefan Lucks för att nämna några. Den officiella Skeins hemsida finns här.
Symmetriska nyckelkrypteringsmetoder är där krypteringens säkerhet huvudsakligen ligger inom en nyckel, som delas mellan två punkter, där data krypteras och där data dekrypteras. Ett mycket bra exempel på hur detta kan fungera gavs av Christian Beikovs "Skapa en krypterings klass med PHP" handledning.
I huvudsak HMAC är som en blandning mellan envägs hash och nyckelbaserad kryptering. HMAC-säkerhet är beroende av den använda nyckelstorleken och styrkan på hashfunktionen den beräknas med. Du kan något jämföra denna metod för att salta lösenord.
";?>
Tja vilken resa! Randomiserande värden, generering av slumpmässiga lösenord, saltning, lagring och autentisering av användare, obfuscation, krypto ... verkar som mycket att ta in. Men värt det! Det är viktigt att veta vilken typ av säkerhet du ska genomföra i dina webbapplikationer, och hur du ska skydda den. Ännu mer är det viktigt att hålla en smart inställning till dessa implementeringar och inte tro att säkerheten endast genomförs med några metoder, men av en kombination av dem med ett streck av kreativitet.