2017-01-14 9 views
12

प्रति this question's related answer के रूप में, मैं इस पीएचपी प्रक्रिया जैसी एक साथ एक पैकेट/खोल समाधान डाल करने के लिए md5 और bufferpackपीएचपी पैक/अनपैक कार्यान्वयन

यहाँ का उपयोग कर प्रयास कर रहा हूँ NodeJS (जावास्क्रिप्ट) में तथापि, पीएचपी पहुंच दी गई है (DaloRADIUS से अनुकूलित:

$challenge = 'c731395aca5dcf45446c0ae83db5319e'; 
    $uamsecret = 'secret'; 
    $password = 'password'; 

    $hexchal = pack ("H32", $challenge); 
    $newchal = pack ("H*", md5($hexchal . $uamsecret)); 
    $response = md5("\0" . $password . $newchal); 
    $newpwd = pack("a32", $password); 
    $pappassword = implode ("", unpack("H32", ($newpwd^$newchal))); 

    echo "Response: ---> ", $response, "\n"; 
    echo "New Password: ---> ", $newpwd, "\n"; 
    echo "Pap Password: ---> ", $pappassword, "\n"; 

ऊपर इको इन:

Responses PHP

,210

प्लेन में ऊपर:

Response: ---> 2d4bd27184f5eb032641137f728c6043 
New Password: ---> password 
Pap Password: ---> 356a1fb08f909fc400dfe448fc483ce3 

जावास्क्रिप्ट में, यहाँ अब मैं क्या कर रहा है:

var challenge = 'c731395aca5dcf45446c0ae83db5319e'; 
    var uamsecret = 'secret'; 
    var password = 'password'; 

    var hexchal = pack.pack("H32", challenge); 
    var newchal = pack.pack("H*", md5(hexchal + uamsecret)); 
    var response = md5("\0" + password + newchal); 
    var newpwd = pack.pack("a32", password); 
    var pappassword = pack.unpack("H32", (newpwd^newchal)).join(""); 

    console.log("Response: --> ", response); 
    console.log("New Password: -->", newpwd); 
    console.log("Pap Password: --->", pappassword); 

कौन सा परिणाम देता है:

Response Javascript

JSON में:

Response Javascript JSON format

प्लेन में:

Response: --> e8a54a55cbcd81dbc2bdfd9b197d62af 
New Password: --> <Buffer > 
Pap Password: ---> NaN 

उपरोक्त सभी के टुकड़े यहां उपलब्ध हैं: RadiusNES

इस पूरी प्रक्रिया में मेरी समझ सबसे अच्छा नहीं है, और अंतर्दृष्टि की सराहना करेंगे और जहां मैं गलत जा रहा हूँ ।

एक मेल नहीं है?

+1

जब भी संभव हो कोशिश करते हैं और स्वरूपित कोड के रूप में पद सादे-पाठ कृपया प्रश्न के शरीर में। कुछ स्क्रीन पढ़ने के लिए असंभव नहीं होने पर ये स्क्रीनशॉट बहुत कठिन हो सकते हैं: वे स्क्रीन पाठकों या अनुवाद उपकरण पर निर्भर हैं। – tadman

+0

@tadman ठीक है, जल्द ही अपडेट हो जाएगा। – Rexford

+0

यह एक बड़ा सौदा नहीं है, लेकिन लंबे समय तक हैश करके टाइप करके अपने परिणामों को पुन: पेश करने का प्रयास किसी के लिए मजेदार नहीं होगा। मुझे लगता है कि आप अपने प्रतिक्रिया, 'हेक्सचाल' और 'न्यूचल' को इकट्ठा करने के लिए उपयोग कर रहे पूर्ववर्ती घटकों पर अधिक बारीकी से देखने के लिए उत्सुक हैं, यह सुनिश्चित करने के लिए कि वे दोनों तरफ समान हैं। – tadman

उत्तर

12

अनुवाद काम नहीं करता है क्योंकि PHP Pack function विभिन्न प्रारूप तारों का उपयोग करता है और तारों को लौटाता है, जबकि Javascript bufferpack module रिटर्न सरणी देता है। इसके अलावा आप जावास्क्रिप्ट में तारों को xor नहीं कर सकते हैं।

जबकि आप जो चाहते हैं उसे करने के लिए मॉड्यूल हो सकते हैं, मेरे पास हेक्स तारों को पार्स करने के लिए मेरे स्वयं के कार्य हैं। इसके अलावा मैं प्रोटोटाइप को संशोधित करना पसंद करता हूं जो सभी सहमत नहीं हैं, लेकिन इन्हें नियमित कार्यों में परिवर्तित किया जा सकता है।

.pad(32, string)pack('a32', string) रूप में एक ही परिणाम देने के लिए बाहर पैड nulls के साथ एक स्ट्रिंग के लिए प्रयोग किया जाता है:

String.prototype.pad = function(length ,padding) { 

    var padding = typeof padding === 'string' && padding.length > 0 ? padding[0] : '\x00' 
     ,length = isNaN(length) ? 0 : ~~length; 

    return this.length < length ? this + Array(length - this.length + 1).join(padding) : this; 

} 

String.prototype.packHex = function() { 

    var source = this.length % 2 ? this + '0' : this 
     ,result = ''; 

    for(var i = 0; i < source.length; i = i + 2) { 
     result += String.fromCharCode(parseInt(source.substr(i , 2) ,16)); 
    } 

    return result; 

} 

var challenge = 'c731395aca5dcf45446c0ae83db5319e' 
    ,uamsecret = 'secret' 
    ,password = 'password'; 

var hexchal = challenge.packHex(); 
var newchal = md5(hexchal + uamsecret).packHex(); 
var response = md5('\0' + password + newchal); 
var newpwd = password.pad(32); 
var pappassword = ''; 
for(var i = 0; i < newchal.length; i++) { 
    pappassword += (newpwd.charCodeAt(i)^newchal.charCodeAt(i)).toString(16); 
} 

console.log("Response: --> ", response); 
console.log("New Password: -->", newpwd); 
console.log("Pap Password: --->", pappassword); 

दो कार्यों pack समारोह के उपयोग को बदलने के लिए स्ट्रिंग प्रोटोटाइप में परिभाषित कर रहे हैं। यद्यपि यहां जरूरी नहीं है, अगर यह नल के अलावा किसी अन्य चरित्र को स्ट्रिंग पैड करना चाहते हैं तो यह दूसरा पैरामीटर भी लेता है।

.packHexpack('H*' ,string) के बराबर है और हेक्स वर्णों की प्रत्येक जोड़ी के कोड को एक वर्ण में अनुवादित करता है। फ़ंक्शन को आदर्श रूप से स्ट्रिंग का परीक्षण करने के लिए अधिक सत्यापन की आवश्यकता होती है, यदि उपयोग किया जाना है तो एक वैध हेक्स एक है।

इनपुट परिभाषित करने के बाद, अगली चार पंक्तियां इसके बजाय pack के बजाय इन कार्यों का उपयोग करके चर सेट करती हैं।

क्योंकि जावास्क्रिप्ट मूल रूप से तारों को xor नहीं कर सकता है, तो आपको प्रत्येक वर्ण निकालने के लिए एक लूप का उपयोग करने की आवश्यकता है, इसे एक संख्यात्मक में परिवर्तित करें, उन मानों को xor करें, फिर परिणाम को वापस एक वर्ण में परिवर्तित करें ताकि पैपस्वर्ड स्ट्रिंग बना सके।

लौट यही होगा, मेरे लिए:

Response: --> – "fbfd42ffde05fcf8dbdd02b7e8ae2d90" 
New Password: --> – "password������������������������" 
Pap Password: ---> – "dcbdacb03f5d38ca33c128b931c272a" 

कौन सा परिणाम है, लेकिन दुर्भाग्य से PHP कोड से पर एक अलग।

ऐसा इसलिए है क्योंकि PHP की स्थापना को आंतरिक रूप से आईएसओ -885 9 -1 एन्कोडिंग का उपयोग करने के लिए कॉन्फ़िगर किया गया है, जबकि जावास्क्रिप्ट मूल रूप से यूटीएफ -16 का उपयोग करता है।

यह सामान्य उपयोग में कोई समस्या नहीं है, लेकिन इसका मतलब है कि संबंधित md5 फ़ंक्शन अलग-अलग मान देख रहे होंगे और इसलिए एक अलग हैश वापस कर देंगे।

मान लें कि आप एक PHP बैकएंड का उपयोग करके प्रमाणीकरण दिनचर्या लिख ​​रहे हैं, आपको स्पष्ट रूप से लगातार परिणाम की आवश्यकता होगी। संगतता के लिए जावास्क्रिप्ट मानों के एन्कोडिंग को परिवर्तित करने के लिए मॉड्यूल उपलब्ध हो सकते हैं, लेकिन PHP कोड में परिवर्तन करना बहुत आसान है।

क्योंकि हम जानते हैं हेक्स तार एक बाइट हो जाएगा, जावास्क्रिप्ट को प्रभावी ढंग से उपयोग कर रहा है UTF-8, इसलिए पीएचपी utf8_encode() समारोह का उपयोग कर उन्हें md5ing से पहले पैक हेक्स तार कन्वर्ट करने के द्वारा एक ही कर सकते हैं।

मूल रूप से मैंने सोचा था कि जावास्क्रिप्ट आंतरिक रूप से एन्कोडेड हेक्स वर्णों को उनके यूनिकोड समकक्षों में परिवर्तित कर रहा था, लेकिन ऐसा नहीं था। इसके बजाय यह जावास्क्रिप्ट में इस्तेमाल किया जा रहा md5 मॉड्यूल था जो इनपुट पर यूटीएफ -8 रूपांतरण कर रहा था।

इससे दो संभावित विकल्प निकलते हैं।


1. उपयोग UTF-8 पीएचपी

आप UTF-8 एन्कोडिंग का उपयोग करने के अपने PHP सर्वर पुनः कॉन्फ़िगर कर सकते यदि संभव हो तो। या फिर आप एक ही प्रक्रिया के रूप में जावास्क्रिप्ट में हो रहा है दर्पण utf8_encode() समारोह का उपयोग करने के अपनी स्क्रिप्ट को बदल सकते हैं, और UTF-8 में हेक्स पैक तार परिवर्तित उन्हें md5()

$challenge = 'c731395aca5dcf45446c0ae83db5319e'; 
$uamsecret = 'secret'; 
$password = 'password'; 

$hexchal = pack ("H32", $challenge); 
$newchal = pack ("H*", md5(utf8_encode($hexchal) . $uamsecret)); 
$response = md5("\0" . $password . utf8_encode($newchal)); 
$newpwd = pack("a32", $password); 
$pappassword = implode ("", unpack("H32", ($newpwd^$newchal))); 

echo "Response: ---> ", $response, "\n"; 
echo "New Password: ---> ", $newpwd, "\n"; 
echo "Pap Password: ---> ", $pappassword, "\n"; 

को गुजर यह तो एक ही रिटर्न से पहले Javscript के रूप में परिणाम:

Response: ---> fbfd42ffde05fcf8dbdd02b7e8ae2d90 
New Password: ---> password 
Pap Password: ---> dcbdacb03f5d38ca33c128b9310c272a 



2. बदलें जावास्क्रिप्ट में

md5 मॉड्यूल

मुझे लगता है कि आप bluimp JavaScript-MD5 मॉड्यूल का उपयोग कर रहे हैं, क्योंकि यह आपके द्वारा लिंक किए गए DaloRADIUS दिनचर्या द्वारा उपयोग किया जाता है। आप यूटीएफ -8 रूपांतरण को बाईपास करने के लिए इसे पैच कर सकते हैं।

इस तरीके से आप इसे पैच कर सकते हैं, लेकिन लाइन 25 9 पर md5() फ़ंक्शन की परिभाषा है। यह इनपुट विकल्पों को पार्स करने के लिए बस if कथन का एक सेट है और उपयुक्त आंतरिक फ़ंक्शन को कॉल करता है।

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

हालांकि रूपांतरण को आसानी से हटाने के लिए इनपुट को अपरिवर्तित करने के लिए str2rstrUTF8() को बदलने का आसान तरीका है। इस समारोह लाइन 239 पर पाया जा सकता है, बदल रहा है यह सिर्फ इस प्रकार रूपांतरण बंद हो जाएगा पढ़ने के लिए:

function str2rstrUTF8 (input) { 
    return input 
} 

वैकल्पिक रूप से अनावश्यक समारोह को दूर करने के आप कॉल के बजाय सिर्फ यह करने के लिए संदर्भ निकाल सकते हैं। लाइन 246 से शुरू होने को पढ़ने के लिए इस प्रकार समारोह बदलें:

function rawMD5 (s) { 
    return rstrMD5(s) 
} 

लाइन 252 पर rawHMACMD5() समारोह भी है जो आप भी स्थिरता के लिए पैच करने के लिए चाहते हो सकता है str2rstrUTF8() समारोह के लिए कॉल शामिल है, लेकिन यह ऊपर दिनचर्या के लिए आवश्यक नहीं है । उस फ़ंक्शन को इसके बजाय कहा जाता है जब key hash प्रदान करने के लिए दूसरा पैरामीटर पास किया जाता है, मूल फीचर md5() फ़ंक्शन में कोई सुविधा उपलब्ध नहीं है।

उन परिवर्तनों का या तो करने के बाद जावास्क्रिप्ट दिनचर्या अब अपने मूल (ISO-8859-1 का प्रयोग करके) PHP कोड के रूप में ही उत्पादन रिटर्न:

Response: --> – "2d4bd27184f5eb032641137f728c6043" 
New Password: --> – "password������������������������" 
Pap Password: ---> – "356a1fb08f909fc40dfe448fc483ce3" 
+0

क्या यूटीएफ का उपयोग करने के लिए PHP को बदलने के बजाय आईएसओ -885 9 -1 एन्कोडिंग का उपयोग करने के लिए मेरे जावास्क्रिप्ट को कॉन्फ़िगर करने का कोई तरीका है? पैपसवर्ड को नेटवर्क एक्सेस सर्वर (राउटर) को चिलिसपॉट सॉफ़्टवेयर चलाने के लिए भेजा जाता है, जो अन-बदले गए PHP से सटीक प्रतिक्रिया की अपेक्षा करता है। इस प्रकार, सटीक प्रतिक्रिया से मेल खाने के लिए जावास्क्रिप्ट पर एन्कोडिंग को बदलने का कोई तरीका है? – Rexford

+0

हां! मेरे पास अभी जवाब को अपडेट करने का समय नहीं है, लेकिन सुबह में ऐसा करेगा। असल में हालांकि मैंने सोचा था कि यह जावास्क्रिप्ट पैक किए गए हेक्स तारों को यूटीएफ में परिवर्तित कर रहा था, लेकिन वास्तव में यह केवल अक्षर कोड छोड़ रहा था और इसके बजाय यह एमडी 5 मॉड्यूल था जो इसके इनपुट स्ट्रिंग को यूटीएफ में परिवर्तित कर रहा था। उस चरण से बचने के लिए पैच करना बहुत आसान है, और ऐसा करने के बाद यह आपके मूल PHP उदाहरण के समान परिणाम देता है। यदि आप खुद को देखना चाहते हैं तो यह md5.js में 'str2rstrUTF8' फ़ंक्शन है जिसे छोड़ने की आवश्यकता है, अन्यथा मैं कल भी पूरा विवरण पोस्ट करूंगा। – Michael

+0

मैं 'str2rstrUTF8' पर एक नज़र डालेगा। इंगित करने के लिए धन्यवाद। आपको समय मिलने पर जवाब में शामिल करने की भी सराहना होगी। – Rexford