2009-06-30 4 views
12

मैं एक कोड ऐसा ही कुछ हो जाता है है:क्या मुझे mcrypt_decrypt के बाद डिक्रिप्टेड स्ट्रिंग को ट्रिम करना चाहिए?

$cipher_alg = MCRYPT_RIJNDAEL_128; 
$decrypted_string = mcrypt_decrypt($cipher_alg, $key, 
$encrypted_string , MCRYPT_MODE_CBC, trim(hex2bin(trim($hexiv)))); 

मुझे चिंता है कि mcrypt_decrypt डिकोडिंग वापस या $decrypted_string के सामने में एक नि: शुल्क खाली स्थान या अशक्त पात्रों का परिचय देंगे करने की प्रक्रिया में।

तो क्या मुझे इसे ट्रिम करना चाहिए?

नोट: मैं कोड चला सकता था और इसे ढूंढ सकता था। लेकिन चूंकि मैं अपने बिंदु को साबित करने (या अस्वीकार करने के लिए पर्याप्त नमूने कभी नहीं चला सकता, इसलिए मुझे कुछ ठोस और सैद्धांतिक उत्तर चाहिए, शायद mcrypt_decrypt एल्गोरिदम के आंतरिक कार्य के आधार पर। एक और कारण मैं पूछता हूं कि मेरा मानना ​​है कि यह दूसरों की मदद करने जा रहा है।

नोट 2: the answer below (now deleted and only 10K users can see it) साथ होते हुए भी, ऐसा लगता है कि examples here सही decrypted स्ट्रिंग पाने के लिए ट्रिमिंग का उपयोग करते हैं।

+0

गलत जानकारी के लिए खेद है, एनजी, जब मैंने मैक्रिप्ट का इस्तेमाल किया तो ऐसा लगता है कि मैंने सीबीसी मोड का उपयोग किया था। –

+0

एर ... मैंने सीबीसी मोड का उपयोग नहीं किया था ... :-( –

उत्तर

18

असल में दोनों mcrypt_encrypt() और mcrypt_decrypt() के साथ ही अन्य एन/डिक्रिप्शन functons (जैसे mcrypt_generic() या mdecrypt_generic()) पैड $data पैरामीटर n * <<blocksize>> की लंबाई करने के लिए करते हैं। पैडिंग चरित्र NUL वर्ण (\x0 या \0) है जबकि <<blocksize>> साइफर और ब्लॉक सिफर मोड का उपयोग करता है। आपको Block cipher modes of operation और Padding (cryptography) पर एक नज़र रखना चाहिए।

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

cast-128 
    cbc: 8 bytes 
    cfb: 8 bytes 
    ctr: 8 bytes 
    ecb: 8 bytes 
    ncfb: 8 bytes 
    nofb: 8 bytes 
    ofb: 8 bytes 
    stream: not supported 
gost 
    cbc: 8 bytes 
    cfb: 8 bytes 
    ctr: 8 bytes 
    ecb: 8 bytes 
    ncfb: 8 bytes 
    nofb: 8 bytes 
    ofb: 8 bytes 
    stream: not supported 
rijndael-128 
    cbc: 16 bytes 
    cfb: 16 bytes 
    ctr: 16 bytes 
    ecb: 16 bytes 
    ncfb: 16 bytes 
    nofb: 16 bytes 
    ofb: 16 bytes 
    stream: not supported 
twofish 
    cbc: 16 bytes 
    cfb: 16 bytes 
    ctr: 16 bytes 
    ecb: 16 bytes 
    ncfb: 16 bytes 
    nofb: 16 bytes 
    ofb: 16 bytes 
    stream: not supported 
arcfour 
    cbc: not supported 
    cfb: not supported 
    ctr: not supported 
    ecb: not supported 
    ncfb: not supported 
    nofb: not supported 
    ofb: not supported 
    stream: 1 bytes 
cast-256 
    cbc: 16 bytes 
    cfb: 16 bytes 
    ctr: 16 bytes 
    ecb: 16 bytes 
    ncfb: 16 bytes 
    nofb: 16 bytes 
    ofb: 16 bytes 
    stream: not supported 
loki97 
    cbc: 16 bytes 
    cfb: 16 bytes 
    ctr: 16 bytes 
    ecb: 16 bytes 
    ncfb: 16 bytes 
    nofb: 16 bytes 
    ofb: 16 bytes 
    stream: not supported 
rijndael-192 
    cbc: 24 bytes 
    cfb: 24 bytes 
    ctr: 24 bytes 
    ecb: 24 bytes 
    ncfb: 24 bytes 
    nofb: 24 bytes 
    ofb: 24 bytes 
    stream: not supported 
saferplus 
    cbc: 16 bytes 
    cfb: 16 bytes 
    ctr: 16 bytes 
    ecb: 16 bytes 
    ncfb: 16 bytes 
    nofb: 16 bytes 
    ofb: 16 bytes 
    stream: not supported 
wake 
    cbc: not supported 
    cfb: not supported 
    ctr: not supported 
    ecb: not supported 
    ncfb: not supported 
    nofb: not supported 
    ofb: not supported 
    stream: 1 bytes 
blowfish-compat 
    cbc: 8 bytes 
    cfb: 8 bytes 
    ctr: 8 bytes 
    ecb: 8 bytes 
    ncfb: 8 bytes 
    nofb: 8 bytes 
    ofb: 8 bytes 
    stream: not supported 
des 
    cbc: 8 bytes 
    cfb: 8 bytes 
    ctr: 8 bytes 
    ecb: 8 bytes 
    ncfb: 8 bytes 
    nofb: 8 bytes 
    ofb: 8 bytes 
    stream: not supported 
rijndael-256 
    cbc: 32 bytes 
    cfb: 32 bytes 
    ctr: 32 bytes 
    ecb: 32 bytes 
    ncfb: 32 bytes 
    nofb: 32 bytes 
    ofb: 32 bytes 
    stream: not supported 
serpent 
    cbc: 16 bytes 
    cfb: 16 bytes 
    ctr: 16 bytes 
    ecb: 16 bytes 
    ncfb: 16 bytes 
    nofb: 16 bytes 
    ofb: 16 bytes 
    stream: not supported 
xtea 
    cbc: 8 bytes 
    cfb: 8 bytes 
    ctr: 8 bytes 
    ecb: 8 bytes 
    ncfb: 8 bytes 
    nofb: 8 bytes 
    ofb: 8 bytes 
    stream: not supported 
blowfish 
    cbc: 8 bytes 
    cfb: 8 bytes 
    ctr: 8 bytes 
    ecb: 8 bytes 
    ncfb: 8 bytes 
    nofb: 8 bytes 
    ofb: 8 bytes 
    stream: not supported 
enigma 
    cbc: not supported 
    cfb: not supported 
    ctr: not supported 
    ecb: not supported 
    ncfb: not supported 
    nofb: not supported 
    ofb: not supported 
    stream: 1 bytes 
rc2 
    cbc: 8 bytes 
    cfb: 8 bytes 
    ctr: 8 bytes 
    ecb: 8 bytes 
    ncfb: 8 bytes 
    nofb: 8 bytes 
    ofb: 8 bytes 
    stream: not supported 
tripledes 
    cbc: 8 bytes 
    cfb: 8 bytes 
    ctr: 8 bytes 
    ecb: 8 bytes 
    ncfb: 8 bytes 
    nofb: 8 bytes 
    ofb: 8 bytes 
    stream: not supported 

इसलिए आप rtrim() करने के लिए है, तो अपने सिफर निश्चित लंबाई ब्लॉकों पर चल रही है डिक्रिप्शन कार्यों का उत्पादन मूल स्ट्रिंग प्राप्त करने के लिए:

$output = rtrim($decrypted, "\0"); 
+1

यह सही समाधान है। डबल कोट्स का उपयोग करना बहुत महत्वपूर्ण है और '0 0' – shadowhand

+2

बीटीडब्ल्यू के आसपास एकल उद्धरण नहीं है, यह बहुत ही असंभव है कि 'ट्रिम (..., "\ 0") का उपयोग करके, कभी भी आपको डिक्रिप्ट किए गए डेटा को तोड़ देगा, भले ही एक गैर-निश्चित ब्लॉक आकार का उपयोग करते समय भी, लेकिन यह * संभव * है जब आप बाइनरी डेटा एन्क्रिप्ट कर रहे हों। – shadowhand

+0

आप एक हैं स्टड @ स्टेफान गेह्रिग। मुझे सिर्फ 'ट्रिम' का उपयोग करके दस लाख उदाहरण मिलते हैं, लेकिन यह वास्तव में मेरे संदर्भ में महत्वपूर्ण सफेद जगह को ट्रिम कर रहा था, और यह सब कुछ फिर से दुनिया के साथ सही हो सकता है। हां, 2 घंटे डिबगिंग के बाद, और फिर खोज रहे हैं एक समाधान और वह सब। – CWSpear

8

TripleDES की मेरी कार्यान्वयन में, मैं decrypted स्ट्रिंग पाया \ 5 या \ 6 वर्णों के साथ गद्देदार था। यह ऊपर उल्लिखित अपेक्षित \ 0 या \ 4 वर्ण या PHP.net उदाहरणों में नहीं था। पैडिंग वर्ण के ASCII मान को निर्धारित करने के लिए ord() फ़ंक्शन का उपयोग करें। ord() एक वर्ण पर काम करता है तो स्ट्रिंग को तोड़ने के लिए str_split() का उपयोग करें या सरणी नोटेशन के साथ सीधे चरित्र तक पहुंचें - $ string [5]।

अंतिम ट्रिम परिणाम - trim($decrypt, "\0..\32");

अंतिम कोड परिणाम -

$key  = "encryption key"; 
    $encrypt = base64_decode($encrypt); 
    $iv_size = mcrypt_get_iv_size(MCRYPT_3DES, MCRYPT_MODE_ECB); 
    $iv   = mcrypt_create_iv($iv_size, MCRYPT_RAND); 
    $decrypt = mcrypt_decrypt(MCRYPT_3DES, $key, $encrypt, MCRYPT_MODE_ECB, $iv); 
    $final  = trim($decrypt, "\0..\32"); // removes potential null padding 
+0

ऐसा लगता है कि कुछ मामलों में, पैडिंग [आरएफसी 5652] (https://tools.ietf.org/html/rfc5652#page-28) के अनुसार निर्धारित की जाती है, जहां चरित्र पैड के लिए उपयोग किया जाता है वास्तव में पैडिंग की मात्रा इंगित करता है। मैं केवल यही चाहता हूं कि मुझे पता था कि कौन सा अहंकार/मोड संयोजन है एस (या अंतर्निहित लाइब्रेरी संस्करण?) यह बनाम सिर्फ "\ 0" का उपयोग कर करेगा! – grossvogel

4

मैं एन्क्रिप्ट/बाइनरी डेटा डिक्रिप्ट करने के लिए किया था। दुर्भाग्य से ट्रिम बाइनरी डेटा तोड़ सकता है और एक वैध चरित्र के बराबर वैध बिट्स को ट्रिम कर सकता है।

बाइनरी डेटा के आकार को सुनिश्चित करने के पहले और एन्क्रिप्शन के बाद एक ही है, रॉकेट Hazmat एक महान जवाब यहां पोस्ट: How can I decrypt binary data that ended with NUL characters in PHP?

सारांश:

// PKCS7 Padding 
$blocksize = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_ECB); 
$pad = $blocksize - (strlen($data) % $blocksize); 
$data .= str_repeat(chr($pad), $pad); 

$encrypted = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $data, MCRYPT_MODE_ECB); 


/* Then somewhere else in your code */ 
$decrypted = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $encrypted, MCRYPT_MODE_ECB); 

// PKCS7 Padding 
$strPad = ord($decrypted[strlen($decrypted)-1]); 
$newData = substr($decrypted, 0, -$strPad); 

मैं उपयोग के बारे में निश्चित नहीं हूँ ईसीबी सीबीसी बनाम ... अनुसंधान के

+0

यह उसी तरह सीबीसी पर लागू होता है। –

0

24 के बाद घंटे की, अंत में यह मेरे लिए काम किया:

function removePadding($decryptedText){ 
    $strPad = ord($decryptedText[strlen($decryptedText)-1]); 
    $decryptedText= substr($decryptedText, 0, -$strPad); 
    return $decryptedText; 
} 
+0

उत्तर कोड शून्य पैडिंग के साथ काम नहीं करेगा जो PHP mcrypt को डिफ़ॉल्ट करता है और यही वह है जो ओपी उपयोग कर रहा है। पीकेसीएस # 7/पीकेसीएस # 5 पैडिंग के लिए वहां एक जांच की आवश्यकता है कि पैडिंग मान्य है। गलत कुंजी के उपयोग पर विचार करें, $ strpad सबसे अधिक संभावना गलत होगी, संभावित रूप से डेटा की लंबाई से अधिक मूल्य। लेकिन एक खराब पैडिंग त्रुटि वापस न करें, जो पैडिंग ऑरैकल बनाता है, इसके बजाय बस कुछ भी नहीं करें। अधिकांश पुस्तकालय पीकेसीएस # 7 पैडिंग का समर्थन करते हैं और स्वचालित रूप से एन्क्रिप्शन पर पैडिंग जोड़ देंगे और डिक्रिप्शन पर पैडिंग हटा देंगे-कुछ भी और ज़रूरत नहीं है। – zaph

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