php - दो-तरफा एन्क्रिप्शन: मुझे उन पासवर्ड को स्टोर करने की आवश्यकता है जिन्हें पुनर्प्राप्त किया जा सकता है




security encryption (6)

मैं एक ऐसा एप्लिकेशन बना रहा हूं जो पासवर्ड संग्रहीत करेगा, जिसे उपयोगकर्ता पुनर्प्राप्त और देख सकता है। पासवर्ड हार्डवेयर डिवाइस के लिए हैं, इसलिए हैश के खिलाफ जांच प्रश्न से बाहर हैं।

मुझे क्या जानने की ज़रूरत है:

  1. मैं PHP में पासवर्ड कैसे एन्क्रिप्ट और डिक्रिप्ट करूं?

  2. पासवर्ड को एन्क्रिप्ट करने के लिए सबसे सुरक्षित एल्गोरिदम क्या है?

  3. मैं निजी कुंजी कहां स्टोर करूं?

  4. निजी कुंजी को संग्रहीत करने के बजाय, क्या यह एक अच्छा विचार है कि उपयोगकर्ताओं को निजी कुंजी दर्ज करने की आवश्यकता हो, जब भी उन्हें पासवर्ड डिक्रिप्ट की आवश्यकता हो? (इस एप्लिकेशन के उपयोगकर्ताओं को भरोसा किया जा सकता है)

  5. पासवर्ड किस प्रकार चोरी और डिक्रिप्ट किया जा सकता है? मुझे किस बारे में पता होना चाहिए?


पासवर्ड हार्डवेयर डिवाइस के लिए हैं, इसलिए हैश के खिलाफ जांच प्रश्न से बाहर हैं

एह? मुझे समझ में नहीं आता क्या आपका मतलब यह है कि पासवर्ड पुनर्प्राप्त करने योग्य होना चाहिए?

जैसा कि अन्य ने कहा है, मैक्रिप्ट एक्सटेंशन बहुत सारे क्रिप्टोग्राफिक कार्यों तक पहुंच प्रदान करता है - हालांकि आप अपने उपयोगकर्ताओं को एक ही टोकरी में अपने सभी अंडों को रखने के लिए आमंत्रित कर रहे हैं - एक जो संभावित रूप से हमलावरों के लिए एक लक्ष्य होगा - और यदि आप यहां तक ​​कि नहीं जानते समस्या को हल करने के तरीके को कैसे शुरू करें, फिर आप अपने उपयोगकर्ताओं को एक अक्षमता कर रहे हैं। आप समझने की स्थिति में नहीं हैं कि डेटा को कैसे सुरक्षित किया जाए।

अधिकांश सुरक्षा भेद्यताएं इस बारे में नहीं आती हैं क्योंकि अंतर्निहित एल्गोरिदम दोषपूर्ण या असुरक्षित है - लेकिन अनुप्रयोग कोड के भीतर एल्गोरिदम का उपयोग करने के तरीके की समस्याओं के कारण।

ऐसा कहकर, एक उचित सुरक्षित प्रणाली बनाना संभव है।

आपको केवल असममित एन्क्रिप्शन पर विचार करना चाहिए यदि आपके पास उपयोगकर्ता के लिए एक सुरक्षित संदेश बनाने की आवश्यकता है जो किसी अन्य (विशिष्ट) उपयोगकर्ता द्वारा पठनीय है। इसका कारण यह है कि इसकी कम्प्यूटेशनल रूप से महंगा है। यदि आप केवल अपने डेटा को दर्ज करने और पुनर्प्राप्त करने के लिए एक संग्रह प्रदान करना चाहते हैं, तो सममित एन्क्रिप्शन पर्याप्त है।

यदि, हालांकि, आप एन्क्रिप्टेड संदेश (या जहां एन्क्रिप्टेड संदेश संग्रहीत किया जाता है) के रूप में उसी स्थान पर संदेश को डिक्रिप्ट करने के लिए कुंजी संग्रहीत करते हैं, तो सिस्टम सुरक्षित नहीं है। उपयोगकर्ता को डिक्रिप्शन कुंजी के रूप में प्रमाणीकृत करने के लिए एक ही टोकन का उपयोग करें (या एसिमेट्रिक एन्क्रिप्शन के मामले में, टोकन का उपयोग निजी कुंजी पास वाक्यांश के रूप में करें)। चूंकि आपको सर्वर पर टोकन स्टोर करने की आवश्यकता होगी, जहां कम से कम अस्थायी रूप से डिक्रिप्शन होता है, हो सकता है कि आप एक गैर-खोज योग्य सत्र संग्रहण सब्सट्रेट का उपयोग करने पर विचार करना चाहें, या टोकन को उस सत्र से जुड़े डेमॉन पर सीधे पास करना चाहें जो स्टोर करेगा स्मृति में टोकन और मांग पर संदेशों का डिक्रिप्शन प्रदर्शन करते हैं।


  1. आपके द्वारा बाद में PHP फ़ंक्शन मैक्रिप्ट ( http://www.php.net/manual/en/intro.mcrypt.php ) है।

इस उदाहरण के लिए मैनुअल से उदाहरण थोड़ा संपादित किया गया है):

<?php
$iv_size = mcrypt_get_iv_size(MCRYPT_BLOWFISH, MCRYPT_MODE_ECB);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
$key = "This is a very secret key";
$pass = "PasswordHere";
echo strlen($pass) . "\n";

$crypttext = mcrypt_encrypt(MCRYPT_BLOWFISH, $key, $pass, MCRYPT_MODE_ECB, $iv);
echo strlen($crypttext) . "\n";
?>

आप अपना पासवर्ड डिक्रिप्ट करने के लिए mcrypt_decrypt का उपयोग करेंगे।

  1. सबसे अच्छा algorithm बल्कि व्यक्तिपरक है - 5 लोगों से पूछें, 5 उत्तरों प्राप्त करें। व्यक्तिगत रूप से यदि डिफ़ॉल्ट (Blowfish) आपके लिए पर्याप्त नहीं है, तो आपको शायद बड़ी समस्याएं हो सकती हैं!

  2. यह देखते हुए कि PHP द्वारा एन्क्रिप्ट करने की आवश्यकता है - सुनिश्चित नहीं है कि आप इसे कहीं भी छुपा सकते हैं - इस पर स्वागत टिप्पणियां। मानक PHP सर्वश्रेष्ठ कोडिंग प्रथाओं बिल्कुल लागू होते हैं!

  3. यह देखते हुए कि एन्क्रिप्शन कुंजी आपके कोड में वैसे भी होगी, सुनिश्चित नहीं है कि आप क्या हासिल करेंगे, आपका शेष एप्लिकेशन सुरक्षित है।

  4. जाहिर है, अगर एन्क्रिप्टेड पासवर्ड और एन्क्रिप्शन कुंजी चुराई जाती है, तो गेम खत्म हो जाता है।

मैं अपने जवाब पर एक सवार डालूंगा - मैं एक PHP क्रिप्टो विशेषज्ञ नहीं हूं, लेकिन, मुझे लगता है कि मैंने जो जवाब दिया है वह मानक अभ्यास है - मैं अन्य टिप्पणियों का स्वागत करता हूं।


मैं केवल सार्वजनिक कुंजी एन्क्रिप्शन का सुझाव दूंगा यदि आप बिना किसी बातचीत के उपयोगकर्ता के पासवर्ड सेट करने की क्षमता चाहते हैं (यह रीसेट और साझा पासवर्ड के लिए आसान हो सकता है)।

सार्वजनिक कुंजी

  1. OpenSSL एक्सटेंशन, विशेष रूप से openssl_public_encrypt और openssl_private_decrypt
  2. यह सीधे आरएसए होगा कि आपका पासवर्ड कुंजी आकार में फिट होगा - पैडिंग, अन्यथा आपको एक सममित परत की आवश्यकता है
  3. प्रत्येक उपयोगकर्ता के लिए दोनों कुंजी स्टोर करें, निजी कुंजी का पासफ़्रेज़ उनका एप्लिकेशन पासवर्ड है

सममित

  1. Mcrypt एक्सटेंशन
  2. एईएस -256 शायद एक सुरक्षित शर्त है, लेकिन यह स्वयं में एक SO सवाल हो सकता है
  3. आप नहीं करते - यह उनका एप्लिकेशन पासवर्ड होगा

दोनों

4 । हां - उपयोगकर्ताओं को हर बार अपना आवेदन पासवर्ड दर्ज करना होगा, लेकिन सत्र में इसे संग्रहीत करना अन्य मुद्दों को उठाएगा

5

  • अगर कोई एप्लिकेशन डेटा चुरा लेता है, तो यह सममित सिफर के रूप में सुरक्षित है (सार्वजनिक कुंजी योजना के लिए, इसका उपयोग निजी कुंजी को पासफ्रेज़ से बचाने के लिए किया जाता है।)
  • आपका आवेदन निश्चित रूप से केवल एसएसएल पर पहुंच योग्य होना चाहिए, अधिमानतः क्लाइंट प्रमाण पत्र का उपयोग करना।
  • प्रमाणीकरण के लिए एक दूसरा कारक जोड़ने पर विचार करें जो प्रति सत्र एक बार उपयोग किया जाएगा, जैसे कि एसएमएस के माध्यम से भेजे गए टोकन।

मैंने ऐसा कुछ करने की कोशिश की लेकिन कृपया ध्यान दें कि मैं क्रिप्टोग्राफर नहीं हूं और न ही मुझे php या किसी प्रोग्रामिंग भाषा के बारे में गहन ज्ञान है। यह सिर्फ एक विचार है। मेरा विचार है कि कुछ फाइल या database (या मैन्युअल रूप से दर्ज करें) में key स्टोर करना है (स्थान) को आसानी से भविष्यवाणी नहीं की जा सकती है (और निश्चित रूप से किसी भी चीज़ को डिक्रिप्ट किया जाएगा, अवधारणा डिक्रिप्शन समय को बढ़ाने के लिए है) और संवेदनशील जानकारी एन्क्रिप्ट करें।

$iv_size = mcrypt_get_iv_size(MCRYPT_BLOWFISH , MCRYPT_MODE_ECB);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
$key = "evenifyouaccessmydatabaseyouwillneverfindmyemail";
$text = "[email protected]";
echo "Key : ".$key."<br/>";
echo "Text : ".$text . "<br/>";
echo "Md5 : ".md5($text). "<br/>";
echo "Sha1 : ".sha1($text). "<br/>";



$crypttext = mcrypt_encrypt(MCRYPT_BLOWFISH , $key, $text, MCRYPT_MODE_ECB, $iv);
echo "Crypted Data : ".$crypttext."<br>";

$base64 = base64_encode($crypttext);
echo "Encoded Data : ".$base64."<br/>";
$decode =  base64_decode($base64);


$decryptdata = mcrypt_decrypt(MCRYPT_BLOWFISH , $key, $crypttext, MCRYPT_MODE_ECB, $iv);

echo "Decoded Data : ".ereg_replace("?", null ,  $decryptdata); 
//event if i add '?' to the sting to the text it works, I don't know why.

कृपया ध्यान दें कि यह सिर्फ एक अवधारणा है। इस कोड पर कोई भी सुधार अत्यधिक सराहनीय होगा।


मैं PHP में पासवर्ड कैसे एन्क्रिप्ट और डिक्रिप्ट करूं? कई एन्क्रिप्शन एल्गोरिदम में से एक को लागू करके। (या कई पुस्तकालयों में से एक का उपयोग करना)

पासवर्ड को एन्क्रिप्ट करने के लिए सबसे सुरक्षित एल्गोरिदम क्या है? कई अलग-अलग एल्गोरिदम हैं, जिनमें से कोई भी 100% सुरक्षित नहीं है। लेकिन उनमें से कई वाणिज्य और यहां तक ​​कि सैन्य उद्देश्यों के लिए पर्याप्त सुरक्षित हैं

मैं निजी कुंजी कहां स्टोर करूं? यदि आपने सार्वजनिक कुंजी - क्रिप्टोग्राफी एल्गोरिदम (जैसे आरएसए) को लागू करने का निर्णय लिया है, तो आप निजी कुंजी स्टोर नहीं करते हैं। उपयोगकर्ता की निजी कुंजी है। आपके सिस्टम में सार्वजनिक कुंजी है जिसे आप चाहें कहीं भी संग्रहीत किया जा सकता है।

निजी कुंजी को संग्रहीत करने के बजाय, क्या यह एक अच्छा विचार है कि उपयोगकर्ताओं को निजी कुंजी दर्ज करने की आवश्यकता हो, जब भी उन्हें पासवर्ड डिक्रिप्ट की आवश्यकता हो? (इस एप्लिकेशन के उपयोगकर्ताओं पर भरोसा किया जा सकता है) ठीक है अगर आपका उपयोगकर्ता हास्यास्पद रूप से लंबे प्राइम नंबर याद कर सकता है - हाँ, क्यों नहीं। लेकिन आम तौर पर आपको सिस्टम के साथ आने की आवश्यकता होगी जो उपयोगकर्ता को कहीं भी अपनी कुंजी स्टोर करने की अनुमति देगा।

पासवर्ड किस प्रकार चोरी और डिक्रिप्ट किया जा सकता है? मुझे किस बारे में पता होना चाहिए? यह इस्तेमाल किए गए एल्गोरिदम पर निर्भर करता है। हालांकि हमेशा यह सुनिश्चित करें कि आप उपयोगकर्ता से या उससे पासवर्ड को अनएन्क्रिप्टेड नहीं भेजते हैं। या तो इसे क्लाइंट पक्ष पर एन्क्रिप्ट / डिक्रिप्ट करें, या https (या सर्वर और क्लाइंट के बीच कनेक्शन को सुरक्षित करने के लिए उपयोगकर्ता अन्य क्रिप्टोग्राफ़िक माध्यम) का उपयोग करें।

हालांकि अगर आपको एन्क्रिप्टेड तरीके से पासवर्ड स्टोर करना है, तो मैं आपको एक साधारण एक्सओआर सिफर का उपयोग करने का सुझाव दूंगा। इस एल्गोरिदम के साथ मुख्य समस्या यह है कि इसे आसानी से आवृत्ति विश्लेषण द्वारा तोड़ दिया जा सकता है। हालांकि आम तौर पर पासवर्ड अंग्रेजी पाठ के लंबे पैराग्राफ से नहीं बने होते हैं, मुझे नहीं लगता कि आपको इसके बारे में चिंता करनी चाहिए। एक्सओआर सिफर के साथ दूसरी समस्या यह है कि यदि आपके पास एन्क्रिप्टेड और डिक्रिप्ट किए गए फॉर्म दोनों में कोई संदेश है तो आप आसानी से पासवर्ड निकाल सकते हैं जिसके साथ इसे एन्क्रिप्ट किया गया था। फिर, आपके मामले में एक बड़ी समस्या नहीं है क्योंकि यह केवल उस उपयोगकर्ता को प्रभावित करती है जो पहले से ही अन्य माध्यमों से समझौता कर चुकी थी।


निजी तौर पर, मैं पोस्ट की गई अन्य लोगों की तरह mcrypt उपयोग करता हूं। लेकिन ध्यान देने के लिए बहुत कुछ है ...

  1. मैं PHP में पासवर्ड कैसे एन्क्रिप्ट और डिक्रिप्ट करूं?

    एक मजबूत वर्ग के लिए नीचे देखें जो आपके लिए सबकुछ का ख्याल रखता है:

  2. पासवर्ड को एन्क्रिप्ट करने के लिए सबसे सुरक्षित एल्गोरिदम क्या है?

    सबसे सुरक्षित उनमे से कोई भी। यदि आप एन्क्रिप्ट करने जा रहे हैं तो सबसे सुरक्षित तरीका सूचना प्रकटीकरण भेद्यता (एक्सएसएस, रिमोट समावेशन इत्यादि) के खिलाफ सुरक्षा करना है। यदि यह निकलता है, तो हमलावर अंततः एन्क्रिप्शन को क्रैक कर सकता है (कुंजी के बिना कोई एन्क्रिप्शन 100% अन-रिवर्सिबल नहीं है - जैसा कि @NullUserException बताता है कि यह पूरी तरह से सच नहीं है। कुछ एन्क्रिप्शन योजनाएं हैं जो OneTimePad जैसे क्रैक करना असंभव हैं) ।

  3. मैं निजी कुंजी कहां स्टोर करूं?

    मैं क्या करूंगा 3 चाबियों का उपयोग करें। एक उपयोगकर्ता द्वारा आपूर्ति की जाती है, एक आवेदन विशिष्ट है और दूसरा उपयोगकर्ता विशिष्ट (नमक की तरह) है। एप्लिकेशन विशिष्ट कुंजी कहीं भी संग्रहीत की जा सकती है (वेब-रूट के बाहर एक कॉन्फ़िगरेशन फ़ाइल में, एक पर्यावरणीय चर, आदि में)। उपयोगकर्ता विशिष्ट एक एन्क्रिप्टेड पासवर्ड के बगल में डीबी में कॉलम में संग्रहीत किया जाएगा। उपयोगकर्ता को आपूर्ति की गई कोई भी संग्रहित नहीं की जाएगी। फिर, आप ऐसा कुछ करेंगे:

    $key = $userKey . $serverKey . $userSuppliedKey;
    

    वहां लाभ यह है कि किसी भी कुंजी के साथ समझौता किए जा रहे डेटा के बिना समझौता किया जा सकता है। यदि कोई SQL इंजेक्शन हमला है, तो वे $userKey प्राप्त कर सकते हैं, लेकिन दूसरे 2 नहीं। यदि कोई स्थानीय सर्वर शोषण करता है, तो वे $userKey और $serverKey प्राप्त कर सकते हैं, लेकिन तीसरे $userSuppliedKey । यदि वे उपयोगकर्ता को रिंच के साथ हराते हैं, तो वे $userSuppliedKey प्राप्त कर सकते हैं, लेकिन दूसरे 2 नहीं (लेकिन फिर, यदि उपयोगकर्ता को रिंच से पीटा जाता है, तो आप बहुत देर हो चुकी हैं)।

  4. निजी कुंजी को संग्रहीत करने के बजाय, क्या यह एक अच्छा विचार है कि उपयोगकर्ताओं को निजी कुंजी दर्ज करने की आवश्यकता हो, जब भी उन्हें पासवर्ड डिक्रिप्ट की आवश्यकता हो? (इस एप्लिकेशन के उपयोगकर्ताओं को भरोसा किया जा सकता है)

    पूर्ण रूप से। असल में, यही एकमात्र तरीका है जो मैं करूँगा। अन्यथा आपको एक टिकाऊ स्टोरेज प्रारूप (एपीसी या memcached, या एक सत्र फ़ाइल में साझा स्मृति) में एक अनएन्क्रिप्टेड संस्करण को स्टोर करने की आवश्यकता होगी। यह स्वयं को अतिरिक्त समझौता करने के लिए उजागर कर रहा है। किसी स्थानीय चर को छोड़कर पासवर्ड के अनएन्क्रिप्टेड संस्करण को कभी भी स्टोर न करें।

  5. पासवर्ड किस प्रकार चोरी और डिक्रिप्ट किया जा सकता है? मुझे किस बारे में पता होना चाहिए?

    आपके सिस्टम के समझौता का कोई भी रूप उन्हें एन्क्रिप्टेड डेटा देखने देगा। अगर वे कोड इंजेक्ट कर सकते हैं या आपके फाइल सिस्टम पर जा सकते हैं, तो वे डिक्रिप्टेड डेटा देख सकते हैं (क्योंकि वे डेटा को डिक्रिप्ट करने वाली फ़ाइलों को संपादित कर सकते हैं)। रीप्ले या एमआईटीएम हमले का कोई भी रूप उन्हें शामिल चाबियों तक पूर्ण पहुंच प्रदान करेगा। कच्चे HTTP यातायात को छूने से उन्हें चाबियाँ भी मिलेंगी।

    सभी ट्रैफिक के लिए एसएसएल का प्रयोग करें। और सुनिश्चित करें कि सर्वर पर कुछ भी कमजोरियों (सीएसआरएफ, एक्सएसएस, एसक्यूएल इंजेक्शन, विशेषाधिकार वृद्धि, रिमोट कोड निष्पादन इत्यादि) है।

संपादित करें: यहां एक मजबूत एन्क्रिप्शन विधि का एक PHP वर्ग कार्यान्वयन है:

/**
 * A class to handle secure encryption and decryption of arbitrary data
 *
 * Note that this is not just straight encryption.  It also has a few other
 *  features in it to make the encrypted data far more secure.  Note that any
 *  other implementations used to decrypt data will have to do the same exact
 *  operations.  
 *
 * Security Benefits:
 *
 * - Uses Key stretching
 * - Hides the Initialization Vector
 * - Does HMAC verification of source data
 *
 */
class Encryption {

    /**
     * @var string $cipher The mcrypt cipher to use for this instance
     */
    protected $cipher = '';

    /**
     * @var int $mode The mcrypt cipher mode to use
     */
    protected $mode = '';

    /**
     * @var int $rounds The number of rounds to feed into PBKDF2 for key generation
     */
    protected $rounds = 100;

    /**
     * Constructor!
     *
     * @param string $cipher The MCRYPT_* cypher to use for this instance
     * @param int    $mode   The MCRYPT_MODE_* mode to use for this instance
     * @param int    $rounds The number of PBKDF2 rounds to do on the key
     */
    public function __construct($cipher, $mode, $rounds = 100) {
        $this->cipher = $cipher;
        $this->mode = $mode;
        $this->rounds = (int) $rounds;
    }

    /**
     * Decrypt the data with the provided key
     *
     * @param string $data The encrypted datat to decrypt
     * @param string $key  The key to use for decryption
     * 
     * @returns string|false The returned string if decryption is successful
     *                           false if it is not
     */
    public function decrypt($data, $key) {
        $salt = substr($data, 0, 128);
        $enc = substr($data, 128, -64);
        $mac = substr($data, -64);

        list ($cipherKey, $macKey, $iv) = $this->getKeys($salt, $key);

        if (!hash_equals(hash_hmac('sha512', $enc, $macKey, true), $mac)) {
             return false;
        }

        $dec = mcrypt_decrypt($this->cipher, $cipherKey, $enc, $this->mode, $iv);

        $data = $this->unpad($dec);

        return $data;
    }

    /**
     * Encrypt the supplied data using the supplied key
     * 
     * @param string $data The data to encrypt
     * @param string $key  The key to encrypt with
     *
     * @returns string The encrypted data
     */
    public function encrypt($data, $key) {
        $salt = mcrypt_create_iv(128, MCRYPT_DEV_URANDOM);
        list ($cipherKey, $macKey, $iv) = $this->getKeys($salt, $key);

        $data = $this->pad($data);

        $enc = mcrypt_encrypt($this->cipher, $cipherKey, $data, $this->mode, $iv);

        $mac = hash_hmac('sha512', $enc, $macKey, true);
        return $salt . $enc . $mac;
    }

    /**
     * Generates a set of keys given a random salt and a master key
     *
     * @param string $salt A random string to change the keys each encryption
     * @param string $key  The supplied key to encrypt with
     *
     * @returns array An array of keys (a cipher key, a mac key, and a IV)
     */
    protected function getKeys($salt, $key) {
        $ivSize = mcrypt_get_iv_size($this->cipher, $this->mode);
        $keySize = mcrypt_get_key_size($this->cipher, $this->mode);
        $length = 2 * $keySize + $ivSize;

        $key = $this->pbkdf2('sha512', $key, $salt, $this->rounds, $length);

        $cipherKey = substr($key, 0, $keySize);
        $macKey = substr($key, $keySize, $keySize);
        $iv = substr($key, 2 * $keySize);
        return array($cipherKey, $macKey, $iv);
    }

    /**
     * Stretch the key using the PBKDF2 algorithm
     *
     * @see http://en.wikipedia.org/wiki/PBKDF2
     *
     * @param string $algo   The algorithm to use
     * @param string $key    The key to stretch
     * @param string $salt   A random salt
     * @param int    $rounds The number of rounds to derive
     * @param int    $length The length of the output key
     *
     * @returns string The derived key.
     */
    protected function pbkdf2($algo, $key, $salt, $rounds, $length) {
        $size   = strlen(hash($algo, '', true));
        $len    = ceil($length / $size);
        $result = '';
        for ($i = 1; $i <= $len; $i++) {
            $tmp = hash_hmac($algo, $salt . pack('N', $i), $key, true);
            $res = $tmp;
            for ($j = 1; $j < $rounds; $j++) {
                 $tmp  = hash_hmac($algo, $tmp, $key, true);
                 $res ^= $tmp;
            }
            $result .= $res;
        }
        return substr($result, 0, $length);
    }

    protected function pad($data) {
        $length = mcrypt_get_block_size($this->cipher, $this->mode);
        $padAmount = $length - strlen($data) % $length;
        if ($padAmount == 0) {
            $padAmount = $length;
        }
        return $data . str_repeat(chr($padAmount), $padAmount);
    }

    protected function unpad($data) {
        $length = mcrypt_get_block_size($this->cipher, $this->mode);
        $last = ord($data[strlen($data) - 1]);
        if ($last > $length) return false;
        if (substr($data, -1 * $last) !== str_repeat(chr($last), $last)) {
            return false;
        }
        return substr($data, 0, -1 * $last);
    }
}

ध्यान दें कि मैं PHP 5.6: hash_equals में जोड़े गए फ़ंक्शन का उपयोग कर रहा हूं। यदि आप 5.6 से कम हैं, तो आप इस विकल्प फ़ंक्शन का उपयोग कर सकते हैं जो डबल एचएमएसी सत्यापन का उपयोग करके एक समय-सुरक्षित तुलना फ़ंक्शन लागू करता है:

function hash_equals($a, $b) {
    $key = mcrypt_create_iv(128, MCRYPT_DEV_URANDOM);
    return hash_hmac('sha512', $a, $key) === hash_hmac('sha512', $b, $key);
}

उपयोग:

$e = new Encryption(MCRYPT_BLOWFISH, MCRYPT_MODE_CBC);
$encryptedData = $e->encrypt($data, $key);

फिर, डिक्रिप्ट करने के लिए:

$e2 = new Encryption(MCRYPT_BLOWFISH, MCRYPT_MODE_CBC);
$data = $e2->decrypt($encryptedData, $key);

ध्यान दें कि मैंने आपको अलग-अलग उदाहरण दिखाने के लिए दूसरी बार $e2 का उपयोग किया था, फिर भी डेटा को ठीक से डिक्रिप्ट करेगा।

अब, यह कैसे काम करता है / इसका उपयोग दूसरे समाधान पर क्यों करें:

  1. चांबियाँ

    • चाबियाँ सीधे उपयोग नहीं की जाती हैं। इसके बजाए, कुंजी को मानक पीबीकेडीएफ 2 व्युत्पन्न द्वारा बढ़ाया जाता है।

    • एन्क्रिप्शन के लिए उपयोग की जाने वाली कुंजी पाठ के प्रत्येक एन्क्रिप्टेड ब्लॉक के लिए अद्वितीय है। इसलिए आपूर्ति की कुंजी एक "मास्टर कुंजी" बन जाती है। इसलिए यह वर्ग साइफर और ऑथ कुंजी के लिए महत्वपूर्ण रोटेशन प्रदान करता है।

    • महत्वपूर्ण नोट , $rounds पैरामीटर पर्याप्त ताकत की वास्तविक यादृच्छिक कुंजी के लिए कॉन्फ़िगर किया गया है (क्रिप्टोग्राफ़िक रूप से न्यूनतम यादृच्छिक रूप से सुरक्षित 128 बिट्स)। यदि आप पासवर्ड, या गैर-यादृच्छिक कुंजी (या कम यादृच्छिक रूप से 128 बिट्स सीएस यादृच्छिक) का उपयोग करने जा रहे हैं, तो आपको यह पैरामीटर बढ़ाना होगा । मैं पासवर्ड के लिए न्यूनतम 10000 का सुझाव दूंगा (जितना अधिक आप बर्दाश्त कर सकते हैं, बेहतर होगा, लेकिन यह रनटाइम में जोड़ देगा) ...

  2. डेटा अखंडता

    • अद्यतन संस्करण ENCRYPT-THEN-MAC का उपयोग करता है, जो एन्क्रिप्टेड डेटा की प्रामाणिकता सुनिश्चित करने के लिए एक बेहतर तरीका है।
  3. एन्क्रिप्शन:

    • यह वास्तव में एन्क्रिप्शन करने के लिए mcrypt का उपयोग करता है। मैं मोड के लिए MCRYPT_BLOWFISH या MCRYPT_RIJNDAEL_128 साइपर और MCRYPT_MODE_CBC का उपयोग करने का सुझाव MCRYPT_MODE_CBC । यह काफी मजबूत है, और अभी भी काफी तेज है (एक एन्क्रिप्शन और डिक्रिप्शन चक्र मेरी मशीन पर लगभग 1/2 सेकंड लेता है)।

अब, पहली सूची से 3 को इंगित करने के लिए, जो आपको देगा वह इस तरह का एक कार्य है:

function makeKey($userKey, $serverKey, $userSuppliedKey) {
    $key = hash_hmac('sha512', $userKey, $serverKey);
    $key = hash_hmac('sha512', $key, $userSuppliedKey);
    return $key;
}

आप इसे makeKey() फ़ंक्शन में खींच सकते हैं, लेकिन चूंकि इसे बाद में फैलाया जा रहा है, इसलिए ऐसा करने के लिए वास्तव में एक बड़ा मुद्दा नहीं है।

जहां तक ​​भंडारण का आकार है, यह सादे पाठ पर निर्भर करता है। Blowfish एक 8 बाइट ब्लॉक आकार का उपयोग करता है, तो आपके पास होगा:

  • नमक के लिए 16 बाइट्स
  • एचएमएसी के लिए 64 बाइट्स
  • डेटा लंबाई
  • पैडिंग ताकि डेटा की लंबाई% 8 == 0 हो

तो 16 वर्ण डेटा स्रोत के लिए, डेटा के 16 वर्ण एन्क्रिप्ट किए जाएंगे। तो इसका मतलब है कि वास्तविक एन्क्रिप्टेड डेटा आकार पैडिंग के कारण 16 बाइट्स है। फिर नमक के लिए 16 बाइट्स और एचएमएसी के लिए 64 बाइट्स जोड़ें और कुल संग्रहित आकार 96 बाइट्स है। तो सबसे अच्छा 80 वर्ण ओवरहेड है, और सबसे खराब 87 चरित्र ओवरहेड ...

मुझे आशा है कि वह मदद करेंगे...

नोट: 12/11/12: मैंने इस वर्ग को बेहतर व्युत्पन्न कुंजी का उपयोग करके, और बेहतर मैक पीढ़ी को ठीक करने के साथ, एक बेहतर बेहतर एन्क्रिप्शन विधि के साथ अपडेट किया है ...





passwords