2012-03-20 6 views
8

यहाँ एक PHP डेमो स्क्रिप्ट एन्क्रिप्ट करता है और decrypts है डेटा:mcrypt_encrypt() मेरी स्ट्रिंग के अंत में बाइनरी वर्ण क्यों डाल रहा है?

<? 

$encryptionkey = 'h8y2p9d1'; 

$card_nbr = "1234"; 
echo "original card_nbr: $card_nbr <br>\n"; 

$card_nbr_encrypted=encrypt_data($card_nbr); 
echo "card_nbr_encrypted: $card_nbr_encrypted <br>\n"; 

$card_nbr_decrypted=decrypt_data($card_nbr_encrypted); 
echo "card_nbr_decrypted: $card_nbr_decrypted <br>\n"; 

$len=strlen($card_nbr_decrypted); 
echo "length: $len <br>\n"; 



function encrypt_data($text){ 
    global $encryptionkey; 
    $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB); 
    $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND); 
    $encrypted_text = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $encryptionkey, $text, MCRYPT_MODE_ECB, $iv); 
    return $encrypted_text; 
} 

function decrypt_data($text){ 
    global $encryptionkey; 
    $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB); 
    $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND); 
    $decrypted_text = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $encryptionkey, $text, MCRYPT_MODE_ECB, $iv); 
    return $decrypted_text; 
} 

?> 


उत्पादन होता है:

original card_nbr: 1234 
card_nbr_encrypted: vY¨(Z$<§G3-žÃ-Éù3Ý2Ê×rz¨VÛ 
card_nbr_decrypted: 1234 (and 28 binary characters) 
length: 32 


उत्पादन सफलतापूर्वक decrypted है, लेकिन 28 बाइनरी वर्ण से जुड़ जाते हैं समाप्त। HTML स्रोत को देखते समय इसे फ़ायरफ़ॉक्स में आसानी से देखा जा सकता है। 32 की स्ट्रिंग लंबाई भी यह दर्शाती है। कोई विचार?

enter image description here

+0

देखें कि क्या यह किसी भी मदद की जा सकती है http://php.net/manual/en/function.base64-encode.php –

+0

@Mian_Khurram_Ijaz मुझे नहीं लगता कि यह – Ben

+0

में मदद करेगा क्यों आउटपुट वास्तव में बाइनरी प्रारूप में है इसलिए इसे नेटवर्क बेस 64_encode में सुरक्षित बनाने के लिए एन्क्रिप्ट और डिक्रिप्ट ठीक काम कर रहा है, इसलिए मैंने सोचा कि बाइनरी वर्ण समस्या है तो बेस 64 का उपयोग करें .. –

उत्तर

8

लौटा हुआ स्ट्रिंग n * blocksize बाइट्स को शून्य वर्ण \0 का उपयोग करके भरने के लिए गद्देदार है, इसलिए आप अतिरिक्त डेटा देख रहे हैं।

यदि आप $card_nbr_decrypted= rtrim($card_nbr_decrypted, "\0"); चलाते हैं तो इसे वास्तविक डेटा वापस करना चाहिए।

+0

'rtrim' का उपयोग कर एक समाधान, निश्चित रूप से टूटा हुआ है, यदि आप चाहते हैं तो टूटा हुआ है मनमाने ढंग से बाइनरी डेटा को एन्क्रिप्ट करने के लिए जो वास्तव में कुछ संख्याओं में समाप्त हो सकता है। उस स्थिति में, आपको या तो स्ट्रिंग आउट-ऑफ-बैंड की लंबाई और 'substr' को उस लंबाई तक वापस ले जाना चाहिए (आसान है, लेकिन स्ट्रिंग की लंबाई को लीक करता है), या एन्क्रिप्टिंग से पहले पैडिंग स्वयं करें - मैं उपयोग करने की अनुशंसा करता हूं PKCS # 7 पैडिंग विधि के रूप में समझना आसान है। – hobbs

+0

पीकेसीएस # 7 के साथ समस्या यह है कि माइक्रिप्ट ने लिखा और बनाए रखने वाले बोझोस ने इसके लिए समर्थन प्रदान किया था। – zaph

3

यह एक known problem हो रहा है। अतिरिक्त एनयूएल को हटाने के लिए डीकोडिंग के बाद rtrim() का उपयोग करें।

2

आप अशक्त बाइट्स प्राप्त कर रहे हैं, क्योंकि आप अपने block cipher mode of operation, जो आपके प्लेन टेक्स्ट के अंत ब्लॉक आकार में फिट पैड के इलेक्ट्रॉनिक कोड ब्लॉक (ईसीबी) उपयोग कर रहे हैं। आपके मामले में ब्लॉक आकार 256 बिट्स है क्योंकि आप MCRYPT_RIJNDAEL_256 का उपयोग कर रहे हैं। MCRYPT_MODE_CFB - - कोई अशक्त बाइट्स, ट्रिम करने की कोई जरूरत

यदि आप सिफर प्रतिक्रिया (CFB) मोड का उपयोग सभी को एक साथ इस गद्दी समस्या से बचने कर सकते हैं। लेकिन, सीएफबी के साथ आपको अपने एन्क्रिप्टेड डेटा को सत्यापित करना चाहिए, यह सत्यापित करने के लिए कि (see "Mallet") के साथ छेड़छाड़ नहीं की गई है। आप एक कार्य कार्यान्वयन का उदाहरण पा सकते हैं: Cryptography For The Average Developer

ध्यान दें, ईसीबी मोड को कम सुरक्षित माना जाता है क्योंकि यह reveal data patterns कर सकता है। इसके अलावा, ईसीबी (और सीबीसी भी पैड के बाद से) padding oracle attack के लिए कमजोर हो सकता है।

-1

मुझे लगता है कि समस्या यह है कि आप बाइनरी डेटा का उपयोग कर रहे हैं जब है:

mcrypt_encrypt - Encrypts दिए गए मापदंडों

आप उपयोग प्लेन टेक्स्ट के लिए base64_encode ($ पाठ) का उपयोग कर सकते के साथ प्लेन टेक्स्ट।

+0

एन्कोडिंग एन्क्रिप्टिंग के समान नहीं है। –

+0

मुझे पता है। लेकिन अगर आप mcrypt_encrypt का उपयोग करते हैं तो एन्कोडिंग के साथ समस्याओं से बचने के लिए बेस 64 सादे टेक्स्ट के रूप में $ टेक्स्ट भेजने के लिए उपयोगी है। आप अन्य 64 उपयोगकर्ताओं के प्रस्ताव के रूप में base64_encode ($ text) या rtrim() का उपयोग कर सकते हैं। – bLuEdDy

संबंधित मुद्दे