Կոդավորումը PHP-ում. Գաղտնագրել, վերծանել տվյալները՝ օգտագործելով PHP գաղտնագրման և իսկորոշման բանալիների բանալի

  • Թարգմանություն
  • Ուսուցողական

Թարգմանչից՝ ծրագրավորման գործընթացում ես երբեք չեմ մոռանում, որ ես վտանգավոր կերպով անընդունակ եմ գաղտնագրության մեջ, և բոլորին խորհուրդ եմ տալիս ելնել այս թեզից (դե, գուցե բացի ձեզանից և այնտեղի այդ թույն տղայից): Սակայն, այսպես թե այնպես, աշխատանքային գործընթացում տվյալների պաշտպանության հետ կապված խնդիրներ են առաջանում, և դրանք պետք է լուծվեն։ Ուստի ձեր ուշադրությանն եմ ներկայացնում ֆինն մշակող Տիմո Հ-ի հոդվածի թարգմանությունը, որն ինձ բավականին հետաքրքիր և օգտակար գտա:

Սա արագ ուղեցույց է, թե ինչպես խուսափել PHP-ում սիմետրիկ գաղտնագրման հետ կապված ընդհանուր թակարդներից:

Մենք կդիտարկենք այն դեպքը, երբ տվյալները մշակվում են սերվերի կողմից (մասնավորապես, սերվերում տեղի է ունենում գաղտնագրում, և տվյալները կարող են ստացվել, օրինակ, հաճախորդից հստակ տեքստի, գաղտնաբառի և այլնի տեսքով), որը բնորոշ դեպք է PHP հավելվածների համար:

Այս ուղեցույցի տեղեկատվությունը չպետք է օգտագործվի գաղտնագրված ցանցային կապեր ստեղծելու համար, որոնք ունեն ավելի բարդ պահանջներ: Նման դեպքերի համար անհրաժեշտ է օգտագործել spied կամ TLS:

Բնականաբար, այստեղ տրված առաջարկությունները PHP-ում գաղտնագրումը կազմակերպելու «միակ հնարավոր միջոցը» չեն։ Այս ուղեցույցի նպատակն է փորձել ավելի քիչ տեղ թողնել սխալների և դժվարին, ոչ միանշանակ որոշումների համար:

Կոդավորման գործառույթներ PHP-ում

Օգտագործեք Mcrypt կամ OpenSSL ընդարձակումներ:

Գաղտնագրման ալգորիթմը և դրա գործողության եղանակը, մեկանգամյա կոդ (նախնականացման վեկտոր)

Օգտագործեք AES-256 CTR ռեժիմում՝ պատահական մեկանգամյա կոդով ( մոտ. թարգմանություն՝ նենց) AES-ը ստանդարտ է, այնպես որ կարող եք օգտագործել ցանկացած ընդարձակման գործառույթները՝ Mcrypt կամ OpenSSL:

Միշտ ստեղծեք նոր մեկանգամյա կոդ: Այս դեպքում դուք պետք է օգտագործեք պատահական թվերի կրիպտոգրաֆիկ անվտանգ աղբյուր: Կարդացեք մի փոքր ավելին պատահական թվերի ստեղծման մասին ստորև: Մեկանգամյա կոդը գաղտնիք չէ և կարող է միացվել գաղտնագրված տեքստին՝ փոխանցման և հետագա վերծանման համար:

Մեկանգամյա կոդը պետք է լինի 128 բիթ (16 բայթ)՝ ընդամենը բայթերի մի շարան՝ առանց որևէ կոդավորման:

Mcrypt ընդլայնման մեջ AES-ը հայտնի է որպես Rijndael-128 ( մոտ. թարգմանություն. չնայած այն հանգամանքին, որ խոսքը AES-256-ի մասին է, սա սխալ չէ: AES-256 != Rijndael-256) OpenSSL-ում, համապատասխանաբար, AES-256-CTR:

Mcrypt օգտագործման օրինակ.
OpenSSL օրինակ.
Ստուգեք, որ գաղտնագրումը ճիշտ է աշխատում՝ օգտագործելով թեստային վեկտորները ( մոտ. թարգմանությունը. AES-256-CTR-ի համար տես F.5.5 պարբերությունը 57-րդ էջում).

CTR ռեժիմի համար կան գաղտնագրված տվյալների ընդհանուր ծավալի որոշ սահմանափակումներ: Հնարավոր է, որ գործնականում չհանդիպեք դրան, բայց նկատի ունեցեք, որ մեկ բանալիով չպետք է գաղտնագրեք 2^64 բայթից ավելի տվյալներ՝ անկախ նրանից՝ դա մեկ երկար հաղորդագրություն է, թե շատ կարճ։

CTR ռեժիմը մնում է կայուն միայն այն դեպքում, եթե դուք չեք օգտագործում նույն մեկանգամյա կոդը նույն բանալիով: Այդ իսկ պատճառով կարևոր է ստեղծել մեկանգամյա կոդեր՝ օգտագործելով պատահականության գաղտնագրորեն ուժեղ աղբյուր: Բացի այդ, սա նշանակում է, որ դուք չպետք է կոդավորեք ավելի քան 2^64 հաղորդագրություն մեկ բանալիով: Քանի որ մեկանգամյա կոդի երկարությունը 128 բիթ է, հաղորդագրությունների քանակի սահմանափակումը (և դրանց համապատասխան մեկանգամյա կոդերը) 2^128/2 կարևոր է ծննդյան պարադոքսի պատճառով ( մոտ. թարգմանություն:).

Եվ հիշեք, որ գաղտնագրումը չի թաքցնի այն փաստը, թե որքան տվյալներ եք ուղարկում: Որպես ծայրահեղ դեպքի օրինակ, եթե գաղտնագրեք միայն «այո» կամ «ոչ» պարունակող հաղորդագրությունները, ակնհայտ է, որ կոդավորումը չի թաքցնի այդ տեղեկատվությունը:

Տվյալների նույնականացում

Միշտ ստուգեք տվյալների իսկությունը և ամբողջականությունը:
Դա անելու համար օգտագործեք MAC գաղտնագրումից հետո: Նրանք. Սկզբում տվյալները գաղտնագրվում են, այնուհետև HMAC-SHA-256-ը վերցվում է ստացված գաղտնագրված տեքստից, ներառյալ հենց ծածկագրված տեքստը և մեկանգամյա ծածկագիրը:

Ապակոդավորելիս նախ ստուգեք HMAC-ը՝ օգտագործելով համեմատական ​​ալգորիթմ, որը դիմացկուն է ժամանակային հարձակումներին: Մի համեմատեք $user_submitted_mac-ը և $calculated_mac-ը` օգտագործելով == կամ === համեմատական ​​օպերատորները: Նույնիսկ ավելի լավ է օգտագործել «HMAC կրկնակի ստուգում»:

Եթե ​​HMAC ստուգումը հաջող է, ապա գաղտնազերծումը կարող է ապահով կերպով իրականացվել: Եթե ​​HMAC-ը հարմար չէ, անմիջապես անջատեք:

Կոդավորման և նույնականացման բանալիներ

Իդեալում, օգտագործեք բանալիներ, որոնք ստացվում են գաղտնագրորեն ուժեղ պատահականության աղբյուրից: AES-256-ը պահանջում է 32 բայթ պատահական տվյալներ («հում» տող. բիթերի հաջորդականություն՝ առանց որևէ կոդավորման օգտագործման):

Եթե ​​հավելվածն աշխատում է 5.5-ից ցածր PHP տարբերակով, որը չունի PBKDF2-ի ներկառուցված ներդրում, ապա դուք ստիպված կլինեք օգտագործել ձեր սեփական կատարումը PHP-ում, որի օրինակը կարող եք գտնել այստեղ՝ https://defuse: ca/php-pbkdf2.htm. Ուշադիր եղեք, որ հենվելով ձեր սեփական ներդրման վրա, կարող է բանալին ճիշտ չլուծվել, ինչպես դա անում է ներկառուցված hash_pbkdf2() ֆունկցիան:

Մի օգտագործեք նույն բանալին կոդավորման և նույնականացման համար: Ինչպես նշվեց վերևում, գաղտնագրման բանալիի համար պահանջվում է 32 բայթ, իսկ իսկորոշման բանալի (HMAC) համար՝ 32 բայթ: PBKDF2-ով դուք կարող եք գաղտնաբառից վերցնել 64 բայթ և օգտագործել, ասենք, առաջին 32 բայթը որպես գաղտնագրման բանալի, իսկ մնացած 32 բայթը՝ նույնականացման բանալիի համար:

Եթե ​​ձեր գաղտնաբառերը պահվում են ֆայլում, օրինակ, որպես HEX տող, մի վերակոդավորեք դրանք նախքան դրանք գաղտնագրման գործառույթներին սնուցելը: Փոխարենը, օգտագործեք PBKDF2՝ HEX կոդավորված բանալիներն ուղղակիորեն բարձրորակ գաղտնագրման կամ նույնականացման բանալի վերածելու համար: Կամ օգտագործեք SHA-256 առանց լրացուցիչ կոդավորման ելքի (ընդամենը 32 բայթ տող) գաղտնաբառերը հաշելու համար: Գաղտնաբառի կանոնավոր հեշինգի օգտագործումը բավականաչափ էնտրոպիա է ապահովում: Ավելի մանրամասն ներկայացված են հետևյալ պարբերություններում:

Բանալին ձգվող

Նախ, դուք պետք է խուսափեք ցածր էնտրոպիայի ստեղների օգտագործումից: Բայց այնուամենայնիվ, եթե ձեզ անհրաժեշտ է օգտագործել, օրինակ, օգտվողի գաղտնաբառերը, ապա դուք պետք է անպայման օգտագործեք PBKDF2 մեծ թվով կրկնություններ, որպեսզի առավելագույնի հասցնեք հիմնական անվտանգությունը:

PBKDF2-ի պարամետրերից մեկը հեշինգի կրկնությունների քանակն է: Եվ որքան բարձր է այն, այնքան ավելի մեծ է բանալին, որի վրա կարող եք ապավինել: Եթե ​​ձեր կոդը աշխատում է 64-բիթանոց հարթակում, օգտագործեք SHA-512 որպես հեշինգի ալգորիթմ PBKDF2-ի համար: 32-բիթանոց հարթակի համար օգտագործեք SHA-256:

Այնուամենայնիվ, հնարավոր չէ համեմատաբար մեծ թվով կրկնություններ օգտագործել առցանց հավելվածներում՝ DoS հարձակման ռիսկի պատճառով: Հետևաբար, առանցքային որակն այնքան բարձր չի լինի, որքան օֆլայն հավելվածներում, որոնք կարող են իրենց թույլ տալ մեծ թվով կրկնություններ՝ առանց նման ռիսկի: Որպես կանոն, առցանց հավելվածների համար ընտրվում է հեշինգի նման քանակի կրկնություններ, որպեսզի PBKDF2-ը տևի ոչ ավելի, քան 100 ms:

Այն դեպքում, երբ դուք կարող եք օգտագործել բարձր էնտրոպիայի գաղտնաբառեր, անհրաժեշտ չէ այն ձգել այնպես, ինչպես դա անում եք ցածր էնտրոպիայի գաղտնաբառերի դեպքում: Օրինակ, եթե դուք ստեղծում եք «encryption_master_key» և «auth_master_key»՝ օգտագործելով /dev/urandom, ապա PBKDF2-ի կարիքն ընդհանրապես չկա: Պարզապես համոզվեք, որ օգտագործեք ստեղները որպես բիթերի հաջորդականություն՝ առանց որևէ կոդավորման:

Բացի այդ, PBKDF2-ով դժվար չէ ստանալ և՛ գաղտնագրման, և՛ նույնականացման բանալիներ մեկ հիմնական գաղտնաբառից (պարզապես օգտագործեք փոքր թվով կրկնություններ կամ նույնիսկ մեկ): Սա օգտակար է, եթե դուք ունեք միայն մեկ «հիմնական գաղտնաբառ», որն օգտագործվում է և՛ կոդավորման, և՛ նույնականացման համար:

Բանալինների պահեստավորում և կառավարում

Լավագույնն այն է, որ օգտագործեք առանձին հատուկ հատուկ բանալիների պահպանման սարք (HSM):

Եթե ​​դա հնարավոր չէ, ապա հարձակումը բարդացնելու համար կարելի է օգտագործել բանալի ֆայլի կամ կազմաձևման ֆայլի կոդավորումը (որը պահում է փաստացի գաղտնագրման/նույնականացման բանալիները)՝ օգտագործելով առանձին վայրում պահվող բանալի (տնային գրացուցակից կամ կայքի արմատից դուրս) . Օրինակ, դուք կարող եք օգտագործել Apache միջավայրի փոփոխական httpd.conf-ում` պահելու բանալին, որն անհրաժեշտ է փաստացի բանալիների ֆայլը վերծանելու համար.
SetEnv keyfile_key crypto_strong_high_entropy_key # Դուք կարող եք մուտք գործել այս փոփոխականը PHP-ում՝ օգտագործելով $_SERVER["keyfile_key"] # Կազմաձևի մնացած մասը
Այժմ, եթե կայքի արմատից և ներքևում գտնվող ֆայլերը, ներառյալ բանալիներով ֆայլերը, վտանգված են (օրինակ, եթե կրկնօրինակը արտահոսում է), գաղտնագրված տվյալները կմնան անվտանգ, քանի որ շրջակա միջավայրի փոփոխականում պահվող բանալին չի վնասվել: Կարևոր է հիշել, որ httpd.conf ֆայլերը պետք է առանձին պահուստավորվեն և չվտանգեն keyfile_key փոփոխականը, օրինակ, phpinfo(-ի) ելքի միջոցով:

Եթե ​​դուք ֆայլ եք օգտագործում կազմաձևման պարամետրի փոխարեն, հնարավոր է կազմակերպել ստեղների ռոտացիա: Վատագույն դեպքում, եթե հակառակորդը ստացել է ձեր գաղտնագրման և իսկորոշման բանալիները՝ առանց նկատելու, ապա ստեղները որոշ ընդմիջումներով պտտելը կարող է սահմանափակել նրանց հասանելիությունը (ենթադրելով, որ նրանք չեն կարող ստանալ նոր բանալիներ): Այս տեխնիկան կօգնի նվազեցնել վնասը, քանի որ թշնամին չի կարողանա անվերջ օգտագործել վտանգված բանալիները:

Տվյալների սեղմում

Ընդհանուր առմամբ, դուք չպետք է սեղմեք սկզբնաղբյուր տեքստը նախքան այն գաղտնագրելը: Սա կարող է հակառակորդին տալ վերլուծության լրացուցիչ գործիք:

Օրինակ, եթե նստաշրջանի տվյալները պահում եք կոդավորված թխուկներում, որոնցից մի քանիսը տրամադրվում են օգտագործողի կողմից, իսկ որոշները ներկայացնում են գաղտնի տեղեկատվություն, հակառակորդը կարող է լրացուցիչ տեղեկություններ իմանալ գաղտնիքի մասին՝ որպես սովորական օգտվող ուղարկելով որոշ հատուկ մշակված տվյալներ և չափել, թե ինչպես է փոխվում ստացված գաղտնագրված տեքստերի երկարությունը:

Տեքստն ավելի արդյունավետ է սեղմվում, եթե կան կրկնվող տարածքներ: Օգտվողի տվյալները շահարկելով՝ կարող եք ընտրել այնպես, որ մասամբ համընկնի գաղտնի տվյալների հետ։ Որքան մեծ է համընկնում, այնքան փոքր է ելքային ծածկագրված տեքստը: Այս տեսակի հարձակումը կոչվում է ՀԱՆՑԱԳՈՐԾՈՒԹՅՈՒՆ:

Եթե ​​տվյալները սեղմելու դժվարություն չունեք, մի սեղմեք դրանք:

Սերվերի միջավայր

Որպես ընդհանուր կանոն, դուք չպետք է տեղադրեք անվտանգության զգայուն հավելվածներ ընդհանուր սերվերի վրա: Օրինակ՝ ընդհանուր հոսթինգում, որտեղ հակառակորդը կարող է մուտք գործել վիրտուալ մեքենա նույն ֆիզիկական սերվերի վրա, ինչ դուք:

Կան տարբեր պատճառներ, որոնք համատեղ սերվերները դարձնում են կասկածելի վայր անվտանգության համար կարևոր հավելվածներ հյուրընկալելու համար: Օրինակ, վերջերս վիրտուալ սերվերների միջև հարձակումներ են ցուցադրվել՝ eprint.iacr.org/2014/248.pdf: Սա լավ հիշեցում է, որ հարձակողական մեթոդները չեն նսեմացնում, այլ ավելի շուտ հղկվում և բարելավվում են ժամանակի ընթացքում: Նման որոգայթները միշտ պետք է հաշվի առնել։

Փորձագետի խորհրդատվություն

Վերջին, բայց ոչ պակաս կարևորը, խորհրդակցեք փորձագետի հետ՝ ստուգելու ձեր անվտանգության կոդը:

(PHP 4, PHP 5, PHP 7)

crypt — Միակողմանի տողերի հեշում

Զգուշացում

Այս ֆունկցիան (դեռևս) երկուական անվտանգ չէ:

Նկարագրություն

դամբարանը (տող $str [, լար $աղ]): լար

ծպտյալ ()կվերադարձնի հեշացված տողը՝ օգտագործելով Unix DES-ի վրա հիմնված ստանդարտ ալգորիթմը կամ այլընտրանքային ալգորիթմները, որոնք կարող են հասանելի լինել համակարգում:

Աղի պարամետրը պարտադիր չէ: Այնուամենայնիվ, ծպտյալ ()ստեղծում է թույլ հեշ առանց աղի: PHP 5.6 կամ ավելի նոր տարբերակն առանց դրա բարձրացնում է E_NOTICE սխալ: Համոզվեք, որ նշեք բավականաչափ ուժեղ աղ ավելի լավ անվտանգության համար:

password_hash()օգտագործում է ուժեղ հեշ, առաջացնում է ուժեղ աղ և ինքնաբերաբար կիրառում է համապատասխան ռաունդներ: password_hash()պարզ է ծպտյալ ()փաթաթան և համատեղելի գաղտնաբառի առկա հեշերի հետ: Օգտագործումը password_hash()խրախուսվում է.

Որոշ օպերացիոն համակարգեր աջակցում են մեկից ավելի տեսակի հեշ: Փաստորեն, երբեմն DES-ի վրա հիմնված ստանդարտ ալգորիթմը փոխարինվում է MD5-ի վրա հիմնված ալգորիթմով: Հեշի տեսակը գործարկվում է աղի փաստարկով: Մինչև 5.3-ը, PHP-ն տեղադրման ժամանակ կորոշի հասանելի ալգորիթմները՝ հիմնվելով համակարգի crypt(-ի վրա): Եթե աղ չտրամադրվի, PHP-ն ինքնաբերաբար կստեղծի կամ ստանդարտ երկու նիշ (DES) աղ, կամ տասներկու նիշ ( MD5), կախված MD5 crypt(-ի) առկայությունից: PHP-ն սահմանում է անվամբ հաստատուն CRYPT_SALT_LENGTHորը ցույց է տալիս առկա հեշերի կողմից թույլատրված ամենաերկար վավերական աղը:

Ստանդարտ DES-ի վրա հիմնված ծպտյալ ()վերադարձնում է աղը որպես արդյունքի առաջին երկու նիշ: Այն նաև օգտագործում է str-ի միայն առաջին ութ նիշերը, ուստի ավելի երկար տողերը, որոնք սկսվում են նույն ութ նիշերով, կստեղծեն նույն արդյունքը (երբ օգտագործվում է նույն աղը):

Համակարգերում, որտեղ crypt() ֆունկցիան աջակցում է մի քանի հեշ տիպերի, հետևյալ հաստատունները սահմանվում են 0 կամ 1՝ կախված տվյալ տիպի առկայությունից.

  • CRYPT_STD_DES- Ստանդարտ DES-ի վրա հիմնված հեշ՝ «./0-9A-Za-z» այբուբենի երկու նիշերի աղով: Salt-ում անվավեր նիշերի օգտագործումը կհանգեցնի crypt()-ի ձախողմանը:
  • CRYPT_EXT_DES- Ընդլայնված DES-ի վրա հիմնված հեշ: «Salt»-ը 9 նիշանոց տող է, որը բաղկացած է ընդգծումից, որին հաջորդում է 4 բայթ կրկնությունների քանակ և 4 բայթ աղ: Սրանք կոդավորված են որպես տպագրվող նիշեր, 6 բիթ մեկ նիշի համար, առաջին հերթին ամենաքիչ կարևոր նիշը: 0-ից 63 արժեքները կոդավորված են որպես «./0-9A-Za-z»: Salt-ում անվավեր նիշերի օգտագործումը կհանգեցնի crypt()-ի ձախողմանը:
  • CRYPT_MD5- MD5 հեշինգ տասներկու նիշի աղով, սկսած $1$-ից
  • CRYPT_BLOWFISH- Blowfish-ը հաշվում է աղով հետևյալ կերպ. «$2a$», «$2x$» կամ «$2y$», ծախսերի երկնիշ պարամետր, «$» և 22 նիշ այբուբենից «./0-9A- Զա-զ». Salt-ում այս տիրույթից դուրս նիշերի օգտագործումը կստիպի crypt()-ին վերադարձնել զրոյական երկարության տողը: Արժեքի երկնիշ պարամետրը հիմքում ընկած Blowfish-ի վրա հիմնված հեշավորման ալգորիթմի համար կրկնվող հաշվարկի բազային-2 լոգարիթմն է և պետք է լինի 04-31 միջակայքում, այս միջակայքից դուրս արժեքները կհանգեցնեն crypt()-ի ձախողմանը: 5.3.7-ից առաջ PHP-ի տարբերակներն աջակցում են միայն «$2a$»-ին որպես աղի նախածանց. PHP 5.3.7-ը ներկայացրել է նոր նախածանցները՝ շտկելու անվտանգության թուլությունը Blowfish-ի իրականացման մեջ: Անվտանգության շտկման ամբողջական մանրամասների համար դիմեք, բայց ամփոփելու համար, միայն PHP 5.3.7 և ավելի նոր տարբերակ ունեցող մշակողները պետք է օգտագործեն «$2y$» նախապատվությունը «$2a$»-ին:
  • CRYPT_SHA256- SHA-256 հեշ տասնվեց նիշի աղով, որը նախածանցով $5$ է: Եթե ​​աղի տողը սկսվում է «rounds=
  • CRYPT_SHA512- SHA-512 հեշ տասնվեց նիշի աղով, որը նախածանցով $6$ է: Եթե ​​աղի տողը սկսվում է «rounds= $", N-ի թվային արժեքը օգտագործվում է ցույց տալու համար, թե քանի անգամ պետք է կատարվի հեշինգի հանգույցը, ինչպես Blowfish-ի ծախսերի պարամետրը: Ռաունդների կանխադրված թիվը 5000 է, կա նվազագույնը 1000 և առավելագույնը 999,999,999: Այս միջակայքից դուրս N-ի ցանկացած ընտրություն կկտրվի մինչև մոտակա սահմանը:

PHP 5.3.0-ի դրությամբ, PHP-ն պարունակում է իր սեփական իրականացումը և կօգտագործի այն, եթե համակարգը չունի աջակցություն մեկ կամ մի քանի ալգորիթմների համար:

Պարամետրեր

Հաշման ենթակա տողը:

Զգուշություն

Օգտագործելով CRYPT_BLOWFISHալգորիթմ, կհանգեցնի նրան, որ str պարամետրը կկտրվի մինչև 72 նիշի առավելագույն երկարությունը:

Ընտրովի աղ տող՝ հաշինգը հիմնելու համար: Եթե ​​չի տրամադրվում, վարքագիծը սահմանվում է ալգորիթմի իրականացման միջոցով և կարող է հանգեցնել անսպասելի արդյունքների:

Վերադարձի արժեքներ

Վերադարձնում է հեշված տողը կամ տողը, որը 13 նիշից ավելի կարճ է և երաշխավորված է, որ կտարբերվի ձախողման դեպքում:

Զգուշացում

Գաղտնաբառերը վավերացնելիս պետք է օգտագործվի տողերի համեմատման ֆունկցիա, որը խոցելի չէ ժամանակային հարձակումների նկատմամբ՝ համեմատելու ելքը: ծպտյալ ()նախկինում հայտնի հեշին: PHP 5.6-ից սկսած ապահովում է hash_equals ()այդ նպատակի համար.

Փոփոխությունների օրագիր

Տարբերակ Նկարագրություն
5.6.5 Երբ «*0» ձախողման տողը տրվում է որպես աղ, «*1»-ն այժմ կվերադարձվի՝ գաղտնաբառի այլ իրականացումներին համապատասխանելու համար: Մինչ այս տարբերակը, PHP 5.6-ը սխալ է վերադարձնում DES հեշը:
5.6.0 Բարձրացրեք E_NOTICE անվտանգության նախազգուշացումը, եթե աղը բաց թողնված է:
5.5.21 Երբ «*0» ձախողման տողը տրվում է որպես աղ, «*1»-ն այժմ կվերադարձվի՝ գաղտնաբառի այլ իրականացումներին համապատասխանելու համար: Մինչ այս տարբերակը, PHP 5.5-ը (և ավելի վաղ մասնաճյուղերը) սխալ էին վերադարձնում DES հեշը:
5.3.7 Ավելացված է $2x$և $2 տարեկան $ Blowfish ռեժիմներ՝ հնարավոր բարձր բիթային հարձակումների դեմ պայքարելու համար:
5.3.2 Ավելացվել է SHA-256 և SHA-512 կրիպտը՝ հիմնված Ուլրիխ Դրեպերի » իրականացման վրա:
5.3.2 Ուղղեց Blowfish-ի վարքագիծը անվավեր ռաունդների վրա՝ վերադարձնելու «ձախողված» տողը («*0» կամ «*1»), այլ ոչ թե հետ ընկնելու DES:
5.3.0 PHP-ն այժմ պարունակում է իր սեփական իրականացումը MD5 crypt-ի, Standard DES-ի, Extended DES-ի և Blowfish ալգորիթմների համար և կօգտագործի այն, եթե համակարգը չունի աջակցություն մեկ կամ մի քանի ալգորիթմների համար:

Օրինակներ

Օրինակ #1 ծպտյալ ()օրինակներ

$hashed_password = crypt ("mypassword"); // թող աղը ինքնաբերաբար ստեղծվի

/* Դուք պետք է փոխանցեք crypt()-ի ամբողջ արդյունքները որպես a համեմատելու աղ
գաղտնաբառը՝ խնդիրներից խուսափելու համար, երբ օգտագործվում են հեշինգի տարբեր ալգորիթմներ: (Ինչպես
վերևում ասվում է, որ ստանդարտ DES-ի վրա հիմնված գաղտնաբառի հեշավորումն օգտագործում է 2 նիշանոց աղ,
բայց MD5-ի վրա հիմնված հեշինգն օգտագործում է 12:) */
if (hash_equals ($hashed_password, crypt ($user_input, $hashed_password))) (
echo «Գաղտնաբառը հաստատված է»: ;
}
?>

Օրինակ #2 Օգտագործելով ծպտյալ () htpasswd-ով

// Սահմանեք գաղտնաբառը
$password = "mypassword" ;

// Ստացեք հեշը, թույլ տալով, որ աղը ինքնաբերաբար ստեղծվի
$hash = crypt ($գաղտնաբառ);
?>

Օրինակ #3 Օգտագործելով ծպտյալ ()տարբեր հեշ տեսակների հետ

/* Այս աղերը միայն օրինակներ են և չպետք է բառացի օգտագործվեն ձեր ծածկագրում:
Դուք պետք է ստեղծեք հստակ, ճիշտ ձևաչափված աղ յուրաքանչյուր գաղտնաբառի համար:
*/
եթե (CRYPT_STD_DES == 1) (
echo «Ստանդարտ DES:» . crypt («rasmuslerdorf», «rl»): «\n» ;
}

եթե (CRYPT_EXT_DES == 1) (
echo "Extended DES:" . crypt ("rasmuslerdorf", "_J9..rasm"): «\n» ;
}

եթե (CRYPT_MD5 == 1) (
արձագանք «MD5:» . crypt ("rasmuslerdorf", "$1$rasmusle$"): «\n» ;
}

եթե (CRYPT_BLOWFISH == 1) (
echo "Blowfish:" . crypt ("rasmuslerdorf" , «$2a$07$usesomesillystringforsalt$») . «\n» ;
}

եթե (CRYPT_SHA256 == 1) (
echo «SHA-256:» . crypt ("rasmuslerdorf" , «$5$rounds=5000$usesomesillystringforsalt$») . «\n» ;
}

եթե (CRYPT_SHA512 == 1) (
echo "SHA-512:" . crypt ("rasmuslerdorf" , «$6$rounds=5000$usesomesillystringforsalt$») . «\n» ;
}
?>

Ցանկացած տեղեկատվություն կարող է գաղտնագրվել կամ վերծանվել, այդ թվում՝ օգտագործելով PHP: Այս լեզուն ունի տվյալների կոդավորման բազմաթիվ հնարավորություններ՝ պարզից մինչև բարդ:

Եկեք նայենք գաղտնագրման հիմնական մեթոդներին

հիմք64- թույլ է տալիս գաղտնագրել և վերծանել տվյալները՝ օգտագործելով MIME base64 ալգորիթմը: Այն չի օգտագործում բանալիներ և հաճախ օգտագործվում է PHP-ում հղումները թաքցնելու համար:

Օրինակներ.
//գաղտնագրել տեքստը
$text = «Հղում»;
echo base64_encode ($text); //Արտադրում է՝ PGEgaHJlZj0iIyI+0KHRgdGL0LvQutCwPC9hPg==
//գաղտնագրում
echo base64_decode ("PGEgaHJlZj0iIyI+0KHRgdGL0LvQutCwPC9hPg==");
?>

Ինչպես տեսնում եք, մենք նախ օգտագործեցինք base64_encode գործողությունը և ստացանք ծածկագիրը. PGEgaHJlZj0iIyI+0KHRgdGL0LvQutCwPC9hPg==, և այնուհետև այն փոխարինեց base64_decode-ով և վերադարձրեց հղումը:

md5- թույլ է տալիս միակողմանիորեն հաշել տվյալները: Այսինքն, ի տարբերություն base64-ի, դուք այլևս չեք կարողանա գաղտնազերծել դրանք: Հաճախ md5-ն օգտագործվում է տվյալների բազայում գաղտնաբառերը պահելու համար, սակայն վերջերս գաղտնագրված md5 համակցությունը հեշտացել է գտնել վերծանման աղյուսակներում, որոնք սիրով տրամադրվում են բազմաթիվ կայքերի և ալգորիթմների կողմից: Հետեւաբար, md5 գաղտնաբառերը պահելու համար ավելի լավ է ալգորիթմները փոխարինել Blowfish-ով։

Օրինակ:

//գաղտնագրել տեքստը
echo md5 («համակցություն»);
?>

Բանալինների կոդավորումը

Իսկ գաղտնագրման/վերծանման վերջին օրինակը, որի մասին ես ուզում էի խոսել, օգտագործում է բանալի (որպես գաղտնաբառ): Այսինքն՝ գաղտնագրման ֆունկցիային եզակի բանալի եք փոխանցում, և դրա հետ մեկտեղ ծածկագրվում է կոդը։ Ապակոդավորելու համար դուք պետք է գործառույթին տրամադրեք գաղտնագրված կոդը և բանալի, որը միայն դուք գիտեք: Կոդի ամենաներքևում գտնվող գործառույթների օգտագործման օրինակ:

ֆունկցիա __encode ($text, $key) (



$enc_text=base64_encode(mcrypt_generic($td,$iv.$text));
mcrypt_generic_deinit ($td);
mcrypt_module_close ($td);
վերադարձնել $enc_text; ))
ֆունկցիա strToHex ($string) (
$hex="";
համար ($i=0; $i< strlen($string); $i++) { $hex .= dechex(ord($string[$i])); }
վերադարձ $ hex; )
ֆունկցիա __decode ($text, $key) (
$td = mcrypt_module_open ("եռապատիկ", "", "cfb", "");
$iv_size = mcrypt_enc_get_iv_size ($td);
$iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
եթե (mcrypt_generic_init ($td, $key, $iv) != -1) (
$ decode_text = substr (mdecrypt_generic ($td, base64_decode ($text)), $iv_size);
mcrypt_generic_deinit ($td);
mcrypt_module_close ($td);
վերադարձնել $decode_text; ))
ֆունկցիա hexToStr ($ hex) (
$string="";
համար ($i=0; $i< strlen($hex)-1; $i+=2) { $string .= chr(hexdec($hex[$i].$hex[$i+1])); }
վերադարձնել $string; )

$str = «Բուլկիներ, որոնք պետք է գաղտնագրվեն:
Բանալով";
$code = strToHex (__encode ($str, «My#key-do-36-simvolov»));
echo «Կոդավորված կոդը՝ «.$code»:
";

$str = __decode(hexToStr($code), «My#key-do-36-simvolov»);
echo «Գաղտնազերծված կոդը՝ «.$str.»
";
?>

Դուք կարող եք գաղտնագրել html բովանդակությունը: Բանալու երկարությունը պետք է լինի ոչ ավելի, քան 36 նիշ:

Այս մեթոդը կարող է օգտագործվել որոշ տվյալների գաղտնագրման և txt ֆայլի կամ տվյալների բազայի մեջ տեղադրելու և բանալիով վերծանման միջոցով ստանալու համար:

Իհարկե, ցանկացած կոդ կարող է վերծանվել/հակել, և սա բացառություն չէ, ուստի օգտագործեք գաղտնագրման ուժեղ մեթոդներ:

Կրիպտոգրաֆիայի հիմնական ճշմարտություններից մեկն այն է, որ դուք չպետք է որևէ բան հորինեք այս ոլորտում, քանի դեռ պրոֆեսիոնալ չեք: Սա մասամբ ճիշտ է, քանի որ բոլոր լավագույնները վաղուց են հորինվել, տառապել և օգտագործվել տասնամյակներ շարունակ տեղեկատվական տեխնոլոգիաների ոլորտում: Ճշմարտության մյուս կողմն այն է, որ գիտելիքի որոշակի ոլորտի զարգացումը տեղի է ունենում միայն թարմ գաղափարների և դրանում օրիգինալ լուծումների մշտական ​​ներհոսքով։

Հասկանալի պատճառներով, մենք նպատակ չենք հետապնդի արդյունաբերական ծածկագրման հսկաների վրա, ինչպիսին է AES-ը, այլ, այսպես ասած, կսուզվենք մեր սեփական կրիպտոգրաֆիկ հետազոտությունների մեջ՝ բլեքջեքով և ուրախությամբ:

Մասամբ այն պատճառով, որ հետաքրքիր է, մասամբ այն պատճառով, որ ձեր սեփականը մոդելավորելով և այն համեմատելով ճանաչված ստանդարտների հետ՝ դուք հստակ տեսնում եք հակադրությունը, արդյունավետ լուծումներն ու բացթողումները, և հասկանում եք, թե ինչի կարող եք ձգտել արդյունավետությունը բարելավելու համար:

Բայց արդեն բավականաչափ ջուր:

Ենթադրենք, մեր վեբ հավելվածը գրված է PHP-ով, կարիք ունի հետադարձելի կոդավորման, և մենք հավատում ենք, որ կարող ենք գրել մեր սեփական ծածկագրման համակարգը:

Այսպիսով, եկեք գրենք մեր սեփական հետադարձելի գաղտնագրման համակարգը մասնավոր և հանրային բանալիներով, որը կունենա քիչ թե շատ անվտանգ գաղտնագրման ալգորիթմի հետևյալ հատկանիշները.

  1. Վերջնական ծածկագրում աղմուկի նշանների առկայությունը:
  2. Յուրաքանչյուր «Ուղարկող-նպատակակետ» ալիքի տեղեկատվությունը կգաղտնագրվի մասնավոր բանալիի միջոցով, և համապատասխան գործառույթը եզակի կլինի յուրաքանչյուր բանալիի համար:
  3. Յուրաքանչյուր հաղորդագրություն կստանա ամփոփ կոդ՝ եզակի կոդ, որը հանդիսանում է անձնական բանալիի և սկզբնական հաղորդագրության գործառույթը: Սա պահանջվում է «աղբյուրի խորհրդանիշի» համապատասխան գործառույթի եզակիությանը հասնելու համար<=>կոդավորված խորհրդանիշ» ոչ միայն «Ուղարկող-ստացող» ալիքի, այլև յուրաքանչյուր առանձին հաղորդագրության համար:

    Այսպիսով, նույնիսկ եթե պատկերացնենք, որ որոշակի հաղորդագրության համար կոդավորված և օրիգինալ նշանների համապատասխանությունը հայտնի է դարձել գաղտնագրման վերլուծության, օրինակ՝ հաճախականության վերլուծության միջոցով, դա որևէ նախապատվություն չի տալիս մեկ այլ հաղորդագրություն ուսումնասիրելիս:

  4. Հաճախականության վերլուծությունը բարդացնելու համար մենք կկոդավորենք յուրաքանչյուր սկզբնական հաղորդագրության խորհրդանիշ երկու գաղտնագրային նշաններով:
Եւ ինչ պատահեց.

Փաստորեն, դուք կարող եք տեսնել վերջնական արդյունքը

SymCoder դասը ներառում է կոդավորման և վերծանման մեթոդներ:

Կոդավորումն իրականացվում է code() մեթոդով, որն ընդունում է սկզբնական հաղորդագրությունը որպես մուտքագրում։

Այստեղ tab_coded-ում ստեղծված համապատասխանության աղյուսակից ստացված հաղորդագրությունը ստեղծում է գաղտնագրված հաղորդագրություն, որը նոսրացվում է ծայրերի երկայնքով և ներսում աղմուկի նշաններով:

Ի դեպ, աղմուկի նշանները եզակի են յուրաքանչյուր ուղարկող-նպատակային ալիքի համար, քանի որ դրանք ստեղծվում են ալիքի ստեղնով, բայց եզակի չեն հաղորդագրությունների համար: Կոդի_սիմվոլներում գաղտնագրման համար օգտագործվող նշաններն են որոշ կետադրական նշաններ և նշաններ, ինչպիսիք են %, @ և այլն:

Յուրաքանչյուր կոդավորված նշանի համար կա երկու նշան code_symbols-ից, հասկանալի պատճառներով, որ դրանք մի քանի անգամ ավելի քիչ են, քան կոդավորված նշանները:

Create_tab_coded նամակագրության աղյուսակը կառուցված է՝ օգտագործելով հաղորդագրության բանալին հեշի թարգմանությունը զանգվածի մեջ, որի տարրերի թիվը հավասար է կոդի խորհրդանիշների զանգվածի տարրերի քանակին: Երկու նիշանոց կոդեր անցնելու մեկնարկային դիրքը նույնպես միշտ տարբեր է և կապված է ալիքի ստեղնի հետ: Սա հնարավորություն է տալիս վստահ լինել, որ կոդավորված նշանների անցման և դրանց համապատասխանող կոդի սիմվոլների ալգորիթմը միշտ (կամ երաշխավորված է հաճախ) տարբեր կլինի:

Օրինակ, «բարև աշխարհ» հաղորդագրությունը, երբ կոդավորված է, ունի հետևյալ տեսքը.

Digest-a00bf11d-&?==&!&?.@.@=!=-.?&1.#&?=:.:.1%!&-%@&@%~&1^#=?%% .!%+.?.~=?..&?%&&:%~.#%@&1&1.#=?.#.?.!&1==&=.-=!

Եվ ահա նույն հաղորդագրությունը կրկին կոդավորված է.

Digest-a00bf11d-=:.?=:&!.?.1&-=:=?.?.=.?.!&=%!=-%@=!%~.=^#.1%%. !%+=:.~.@..==%&&1%~.1%@=?.@.!&=.!&@=:&1.==:=!.1&:

Կարելի է տեսնել, որ նույն հաղորդագրության ամփոփումը նույնն է, բայց ծածկագիրը դառնում է տարբեր. աղմուկի նշաններն ավելացվում են կամայական համընկնումով և կամայական հերթականությամբ յուրաքանչյուր նոր գաղտնագրման համար:

Հաղորդագրություններն ունեն ավելորդություն, որը նվազում է, երբ հաղորդագրության ծավալը մեծանում է, մինչև 10% աղմուկ (ամենակարճ հաղորդագրությունների դեպքում աղմուկը հասնում է 90% կամ ավելի բարձր տոկոսի), գաղտնագրված հաղորդագրության նվազագույն երկարությունը 116 նիշ է: Այս գաղտնագրման մեթոդի թերություններից մեկն այն է, որ կոդավորված հաղորդագրությունները առնվազն կրկնապատկվում են:

Ապակոդավորումը բաղկացած է «կոդի խորհրդանիշ» ձևի հակառակ թարգմանությունից՝ հաղորդագրությունից կտրված աղմուկով բնօրինակ խորհրդանիշը: Ո՞րը կարող է լինել բանալին: Հիմնականում ցանկացած տող, որը եզակի է յուրաքանչյուր նպատակակետ-ընդունիչ զույգի համար:

Օրինակ, եթե դուք ստեղծում եք մեսենջեր հաղորդագրությունների գաղտնագրմամբ, ապա անձնական բանալիի ամենապարզ տարբերակը կարող է լինել md5 ($user_id_1. $salt. $user_id_2), ապա բանալին եզակի կլինի յուրաքանչյուր հաղորդագրության ալիքի համար:

Ենթադրենք, դուք պետք է տվյալների փոխանակում կատարեք երկու սերվերների միջև: Տվյալները գաղտնալսման տրաֆիկից պաշտպանելու համար տվյալները կոդավորված են: Դե, օրինակ, գործողությունների փոխանցում բոտնետում: Սա այն է, ինչ, ըստ էության, գաղտնագրում չէ, այլ կոչվում է կոդավորում, և նման ծածկագիրը վերծանելու համար օգտագործվում են հայտնի գործառույթներ:

Որպես կեղծ կոդավորման մեկ այլ օրինակ, ես կտամ մեկ CMS-ի տվյալների բազայում գաղտնաբառերի «գաղտնագրման» օրինակ. այնտեղ գաղտնաբառերը կոդավորված չեն md5() կամ , այլ պարզապես կոդավորված են base64-ի միջոցով: Նրանք. Երբ տվյալների բազան արտահոսում է, հաքերի համար դժվար չի լինի գաղտնազերծել բոլոր գաղտնաբառերը՝ օգտագործելով ներկառուցված PHP base64_decode() ֆունկցիան։

Մենք պետք է տվյալներ փոխանցենք առանց անհանգստանալու, որ ինչ-որ մեկը կկարողանա գաղտնալսել տեքստը և վերծանել այն: PHP-ն ունի տվյալների գաղտնագրման հանրաճանաչ փաթեթ, որը կոչվում է Mcrypt, որն ապահովում է երկկողմանի գաղտնագրում (այսինքն՝ տվյալների իրական կոդավորումը և վերծանումը):

Mcrypt 2.4.7 տարբերակը աջակցում է հետևյալ սիմետրիկ գաղտնագրման ալգորիթմներին՝ Blowfish, RC2, Safer-sk64 xtea, Cast-256, RC4, Safer-sk128, DES, RC4-iv, Serpent, Enigma, Rijndael-128, Threeway, Rijndael-1: , TripleDES, LOKI97, Rijndael-256, Twofish, Panama, Saferplus և այլն: Յուրաքանչյուր ալգորիթմի մասին ավելի շատ մանրամասներ գրված են Վիքիպեդիայում։

Քանի որ օգտագործվում է սիմետրիկ գաղտնագրում, բանալին պետք է հայտնի լինի երկու կողմերին և գաղտնի մնա:

Լարի կոդավորման և վերծանման օրինակ

mcrypt_module_open("des", "", "ecb", "")
Այս ֆունկցիան բացում է ալգորիթմի մոդուլը և օգտագործվող ռեժիմը։ Այս օրինակի համար DES ալգորիթմը գտնվում է ECB ռեժիմում:

$key = substr ($ key, 0, mcrypt_enc_get_key_size ($td));
Բանալու առավելագույն չափը պետք է ձեռք բերվի mcrypt_enc_get_key_size() ֆունկցիան կանչելով, և դրանից փոքր ցանկացած արժեք ճիշտ կլինի:

$s = mcrypt_generic ($td, $source);
Գաղտնագրելիս տվյալները լրացվում են զրոյական բայթով՝ ապահովելու, որ տվյալների երկարությունը n*blocks է: Բլոկի չափի բլոկի չափը որոշվում է ալգորիթմով (DES-ի համար բլոկի չափը 64 բիթ է): Հետևաբար, գաղտնազերծելիս տողի վերջում կարող է հայտնվել «\0», որը հեռացվում է trim() ֆունկցիայի միջոցով։