2011-06-19 9 views
8

के साथ PHP mcrypt का उपयोग करके मैं php और cipher rijndael से mcrypt का उपयोग करके कुछ टेक्स्ट संदेशों को एन्क्रिप्ट करने की कोशिश कर रहा हूं, लेकिन मुझे MCRYPT_MODE_modename के बारे में निश्चित नहीं है (PHP के मैनुअल के अनुसार ये "ecb", "cbc" , "सीएफबी", "ओबीबी", "एनओएफबी" या "स्ट्रीम" लेकिन मैंने पढ़ा है वास्तव में कुछ और हैं)। मुझे नहीं पता कि प्रत्येक व्यक्ति क्या करता है या उनका उपयोग कैसे किया जाता है।रिजेंडेल/एईएस

मैंने दो चीजें पढ़ीं, कि ईसीबी मोड का उपयोग नहीं किया जाना चाहिए और MCRYPT_RAND न तो। उन्होंने व्याख्या नहीं की क्यों। ईसीबी मोड के लिए मुझे लगता है कि ऐसा इसलिए होता है क्योंकि यह हमेशा एक ही सादे पाठ के लिए एक ही एन्क्रिप्टेड आउटपुट उत्पन्न करता है (शायद इसे हमले के लिए इस्तेमाल किया जा सकता है), MCRYPT_RAND के बारे में कोई जानकारी नहीं है (@azz here द्वारा उल्लिखित)।

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

+0

संबंधित: [कौन सा PHP मैक्रिप्ट साइफर सुरक्षित है?] (Http://stackoverflow.com/questions/2809855/which-php-mcrypt-cipher-is-safest) – hakre

+0

विकिपीडिया में अलग-अलग [cipher का अच्छा विवरण है ब्लॉक मोड] (http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation), वे कैसे काम करते हैं और उनकी ताकत और कमजोरियां। – Tails

+0

एक महान कार्य कार्यान्वयन के लिए [क्रिप्टोग्राफी औसत डेवलपर] [http://www.slideshare.net/ircmaxell/cryptography-for-the-average-developer-1) देखें –

उत्तर

16

ecb सबसे सरल है और कमजोरियां हैं इसलिए इसकी अनुशंसा नहीं की जाती है (http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation)। सीबीसी ecb से काफी मजबूत माना जाता है। कुछ अन्य सीबीसी से भी मजबूत हो सकते हैं लेकिन वे सभी धाराएं संबंधित हैं इसलिए सीबीसी आपकी आवश्यकताओं के अनुरूप होनी चाहिए।

से ... http://us.php.net/manual/en/mcrypt.constants.php ...

  • MCRYPT_MODE_ECB (इलेक्ट्रॉनिक codebook) इस तरह के अन्य कुंजियों को एनक्रिप्ट के रूप में यादृच्छिक डेटा, के लिए उपयुक्त है। चूंकि डेटा छोटा और यादृच्छिक है, ईसीबी के नुकसान का अनुकूल नकारात्मक प्रभाव पड़ता है।
  • MCRYPT_MODE_CBC (सिफर ब्लॉक चेनिंग) विशेष रूप से उन फ़ाइलों को एन्क्रिप्ट करने के लिए उपयुक्त है जहां सुरक्षा ईसीबी पर महत्वपूर्ण रूप से बढ़ी है।
  • MCRYPT_MODE_CFB (साइफर फीडबैक) बाइट स्ट्रीम एन्क्रिप्ट करने के लिए सबसे अच्छा तरीका है जहां एकल बाइट एन्क्रिप्ट किया जाना चाहिए।
  • MCRYPT_MODE_OFB (आउटपुट फीडबैक, 8 बिट में) सीएफबी के साथ तुलनीय है, लेकिन उन अनुप्रयोगों में उपयोग किया जा सकता है जहां त्रुटि प्रसार को बर्दाश्त नहीं किया जा सकता है। यह असुरक्षित है (क्योंकि यह 8 बिट मोड में काम करता है) इसलिए इसका उपयोग करने की अनुशंसा नहीं की जाती है।
  • MCRYPT_MODE_NOFB (आउटपुट फीडबैक, एनबीटी में) ओएफबी के बराबर है, लेकिन अधिक सुरक्षित है क्योंकि यह एल्गोरिदम के ब्लॉक आकार पर चल रहा है।
  • MCRYPT_MODE_STREAM कुछ स्ट्रीम एल्गोरिदम जैसे "वेक" या "आरसी 4" को शामिल करने के लिए एक अतिरिक्त मोड है।

मुझे यकीन नहीं है कि क्यों MCRYPT_RAND के खिलाफ अनुशंसा की जाती है, लेकिन ऐसा इसलिए हो सकता है क्योंकि कई प्रणालियों पर सिस्टम यादृच्छिक संख्या जनरेटर को वास्तव में यादृच्छिक नहीं माना जाता है। केवल दो विकल्प हैं और वे आपके सिस्टम और PHP संस्करण के आधार पर उपलब्ध नहीं हो सकते हैं। से ... http://php.net/manual/en/function.mcrypt-create-iv.php ...

  • चतुर्थ स्रोत MCRYPT_RAND (सिस्टम यादृच्छिक संख्या जनरेटर), MCRYPT_DEV_RANDOM हो सकता है (से/डेटा को पढ़ने देव/यादृच्छिक) और MCRYPT_DEV_URANDOM (/ dev/urandom से डेटा पढ़ने)। 5.3.0 से पहले, MCRYPT_RAND विंडोज पर समर्थित एकमात्र था।

नीचे दिया गया कोड केवल एक त्वरित नमूना है। यह काम करता है लेकिन मैं इसकी ताकत को प्रमाणित नहीं कर सकता।

 

<?php 

// Test code 

    $objEncManager = new DataEncryptor(); 

    $sensitiveData = "7890"; 
    echo "Raw Data: _" . $sensitiveData . "_<br><br>"; 

    $encryptedData = $objEncManager->mcryptEncryptString($sensitiveData); 
    echo "Enc Data: _" . $encryptedData . "_<br><br>"; 
    echo "Enc Data length: " . strlen($encryptedData) . "<br><br>"; 

    $decryptedData = $objEncManager->mcryptDecryptString($encryptedData, $objEncManager->lastIv); 
    echo "D-enc Data: _" . $decryptedData . "_<br><br>"; 

    echo "IV: _" . $objEncManager->lastIv . "_<br><br>"; 


/* 
* Note: These functions do not accurately handle cases where the data 
* being encrypted have trailing whitespace so the data 
*  encrypted by them must not have any. Leading whitespace is okay. 
* 
* Note: If your data needs to be passed through a non-binary safe medium you should 
* base64_encode it but this makes the data about 33% larger. 
* 
* Note: The decryption IV must be the same as the encryption IV so the encryption 
* IV must be stored or transmitted with the encrypted data. 
* From (http://php.net/manual/en/function.mcrypt-create-iv.php)... 
* "The IV is only meant to give an alternative seed to the encryption routines. 
* This IV does not need to be secret at all, though it can be desirable. 
* You even can send it along with your ciphertext without losing security." 
* 
* Note: These methods don't do any error checking on the success of the various mcrypt functions 
*/ 
class DataEncryptor 
{ 
    const MY_MCRYPT_CIPHER  = MCRYPT_RIJNDAEL_256; 
    const MY_MCRYPT_MODE   = MCRYPT_MODE_CBC; 
    const MY_MCRYPT_KEY_STRING = "1234567890-abcDEFGHUzyxwvutsrqpo"; // This should be a random string, recommended 32 bytes 

    public $lastIv    = ''; 


    public function __construct() 
    { 
     // do nothing 
    } 


    /** 
    * Accepts a plaintext string and returns the encrypted version 
    */ 
    public function mcryptEncryptString($stringToEncrypt, $base64encoded = true) 
    { 
     // Set the initialization vector 
      $iv_size  = mcrypt_get_iv_size(self::MY_MCRYPT_CIPHER, self::MY_MCRYPT_MODE); 
      $iv   = mcrypt_create_iv($iv_size, MCRYPT_RAND); 
      $this->lastIv = $iv; 

     // Encrypt the data 
      $encryptedData = mcrypt_encrypt(self::MY_MCRYPT_CIPHER, self::MY_MCRYPT_KEY_STRING, $stringToEncrypt , self::MY_MCRYPT_MODE , $iv); 

     // Data may need to be passed through a non-binary safe medium so base64_encode it if necessary. (makes data about 33% larger) 
      if ($base64encoded) { 
       $encryptedData = base64_encode($encryptedData); 
       $this->lastIv = base64_encode($iv); 
      } else { 
       $this->lastIv = $iv; 
      } 

     // Return the encrypted data 
      return $encryptedData; 
    } 


    /** 
    * Accepts a plaintext string and returns the encrypted version 
    */ 
    public function mcryptDecryptString($stringToDecrypt, $iv, $base64encoded = true) 
    { 
     // Note: the decryption IV must be the same as the encryption IV so the encryption IV must be stored during encryption 

     // The data may have been base64_encoded so decode it if necessary (must come before the decrypt) 
      if ($base64encoded) { 
       $stringToDecrypt = base64_decode($stringToDecrypt); 
       $iv    = base64_decode($iv); 
      } 

     // Decrypt the data 
      $decryptedData = mcrypt_decrypt(self::MY_MCRYPT_CIPHER, self::MY_MCRYPT_KEY_STRING, $stringToDecrypt, self::MY_MCRYPT_MODE, $iv); 

     // Return the decrypted data 
      return rtrim($decryptedData); // the rtrim is needed to remove padding added during encryption 
    } 


} 
?> 
+0

चेतावनी: MCRYPT_RIJNDAEL_256 ब्लॉक के साथ रिजेंडेल सिफर है 256 बिट का आकार, दूसरे शब्दों में, यह एईएस जैसा नहीं है। यह भी ध्यान रखें कि PHP पीकेसीएस # 7 पैडिंग के वास्तविक तथ्य का उपयोग नहीं करता है, और यह बहुत दयालु कुंजी को संभाल नहीं करता है (जहां आवश्यक हो वहां विस्तार और कटौती)। फिर फिर, यादृच्छिक जनरेटर में सुधार हुआ है। –

2

ईसीबी मोड सुरक्षित नहीं है क्योंकि यह एन्क्रिप्टेड डेटा में यादृच्छिकता प्रस्तुत नहीं करता है। इसका मूल रूप से मतलब है कि आप आउटपुट में इनपुट के समान पैटर्न देखेंगे (यानी।छवि को here की सूचना दी गई है, यह लिनक्स का लोगो "टक्स का" एन्क्रिप्टेड "संस्करण है)।

MT_RAND को सुरक्षित नहीं माना जाता है क्योंकि यह ऑपरेटिंग सिस्टम के यादृच्छिक संख्या जेनरेटर (rand() PHP का फ़ंक्शन) का उपयोग करता है।

क्रिप्टोग्राफी प्रयोजनों के लिए MCRYPT_DEV_RANDOM (/ dev/random से डेटा पढ़ें) या MCRYPT_DEV_URANDOM (/ dev/urandom से डेटा पढ़ें) का उपयोग करना बेहतर है।

मैक्रिप्ट के साथ उपलब्ध सबसे अधिक उपयोग और सुरक्षित एन्क्रिप्शन मोड, सीबीसी और सीटीआर मोड हैं और सामान्य उपयोग के मामलों के लिए ठीक हैं। एन्क्रिप्शन + प्रमाणीकरण का उपयोग करना हमेशा बेहतर होता है (यानी एचएमएसी का उपयोग करके एन्क्रिप्ट-फिर-प्रमाणीकृत)। उदाहरण के लिए, प्रमाणीकरण के बिना सीबीसी मोड Padding Oracle attack से प्रभावित होता है।