URL में बेस 64 एन्कोडेड स्ट्रिंग्स पास करना


243

क्या GET मापदंडों के माध्यम से कच्चे base64 एन्कोडेड स्ट्रिंग्स को पास करना सुरक्षित है?



4
नहीं, नहीं - जुड़ा हुआ प्रश्न नया है। तो यह जुड़ा हुआ प्रश्न इस एक का डुप्लिकेट बनाता है ...
सर्ज

जवाबों:


206

नहीं, आपको इसे url-encode करने की आवश्यकता होगी, क्योंकि base64 स्ट्रिंग्स में "+", "=" और "/" अक्षर हो सकते हैं जो आपके डेटा के अर्थ को बदल सकते हैं - एक उप-फ़ोल्डर की तरह दिखते हैं।

मान्य बेस 64 अक्षर नीचे हैं।

ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=

4
URLencoding जगह की बर्बादी है, विशेष रूप से base64 ही अप्रयुक्त कई पात्रों को छोड़ देता है।
माइकल गॉउनी

21
मुझे यकीन नहीं है कि मैं समझ रहा हूं कि आप क्या कह रहे हैं - उपरोक्त सूची में अंतिम तीन वर्णों को छोड़कर किसी भी वर्ण को URL एन्कोडिंग नहीं बदल सकता है, और यह कि उन्हें गलत तरीके से व्याख्या करने से रोकने के लिए है क्योंकि उनके URL में अन्य अर्थ हैं। वही आधार 64 के लिए जाता है, मूल डेटा द्विआधारी या कुछ भी हो सकता है, लेकिन यह एक ऐसे रूप में इनकोड किया गया है जिसे आसानी से प्रोटोकॉल का उपयोग करके प्रसारित किया जा सकता है।
त्यागराज

3
सबसे पहले, आपको '+' से बचना चाहिए क्योंकि यह अंतरिक्ष में परिवर्तित हो सकता है। दूसरे, कम से कम कुछ वर्ण हैं जो URL में उपयोग के लिए सुरक्षित हैं और 'मानक' वर्णसेट में उपयोग नहीं किए गए हैं। आपकी विधि कुछ स्थितियों में तीन बार स्थानांतरित डेटा का आकार भी बढ़ा सकती है; उन पात्रों को किसी अन्य के साथ बदलने के दौरान एक ही लंबाई को संरक्षित करते हुए चाल चलेगी। और यह काफी मानक समाधान भी है।
मिशाल गौरी

8
en.wikipedia.org/wiki/Base64#URL_applications - यह स्पष्ट रूप से कहता है कि भागने 'स्ट्रिंग को अनावश्यक रूप से लंबा बनाता है' और वैकल्पिक चारसेट संस्करण का उल्लेख करता है।
मिशाल गौरी

1
इस उत्तर के कारण, मैंने अपनी समस्या का निदान किया जैसा कि उसने उल्लेख किया है। आधार 64 अक्षरों (+, /, =) में से कुछ को URL प्रसंस्करण के कारण बदल दिया जा रहा था। जब मैंने URL को आधार 64 स्ट्रिंग को इनकोड किया, तो समस्या हल हो गई।
चक क्रट्सिंगर

272

अतिरिक्त base64 चश्मा हैं। ( विशेष के लिए यहां तालिका देखें )। लेकिन अनिवार्य रूप से आपको एन्कोड करने के लिए 65 वर्णों की आवश्यकता होती है: 26 लोअरकेस + 26 अपरकेस + 10 अंक = 62।

आपको दो और ['+', '/'] और एक पैडिंग चार '=' की आवश्यकता है। लेकिन उनमें से कोई भी यूआरएल के अनुकूल नहीं है, इसलिए बस उनके लिए विभिन्न वर्णों का उपयोग करें और आप सेट हैं। ऊपर दिए गए चार्ट के मानक [[- ',' _ '] हैं, लेकिन आप अन्य वर्णों का उपयोग तब तक कर सकते हैं जब तक आप उन्हें एक ही डिकोड करते हैं, और दूसरों के साथ साझा करने की आवश्यकता नहीं होती है।

मैं सिर्फ अपने स्वयं के सहायकों को लिखने की सलाह दूंगा। आधार64_encode के लिए php मैनुअल पेज पर टिप्पणियों से इन्हें पसंद करें :

function base64_url_encode($input) {
 return strtr(base64_encode($input), '+/=', '._-');
}

function base64_url_decode($input) {
 return base64_decode(strtr($input, '._-', '+/='));
}

53
कॉमा को छोड़कर महान समाधान, URL में अनारक्षित नहीं है। मैं '~' (टिल्ड) या '' का उपयोग करने की सलाह देता हूं। (डॉट) के बजाय।
क्रालिक

11
@kralyk: मैं urlencodeरॉडरिगो-सिल्वेरा के उत्तर द्वारा सुझाए अनुसार उपयोग कर रहा हूं । Url लंबाई में कुछ वर्णों को सहेजने के लिए दो नए कार्य बनाना, यह आपके घर में प्रवेश करने जैसा है, केवल दरवाजे का उपयोग करने के बजाय खिड़की से गुजरना।
मार्को डेमायो

5
@MarcoDemaio, यह जाने बिना कि इसका उपयोग कैसे किया जाएगा, यह कहना असंभव है कि यह केवल कुछ वर्ण हैं। हर एन्कोड किए गए चरित्र की लंबाई तिगुनी होगी, और "+++ ..." वैध बेस 64 स्ट्रिंग क्यों नहीं होगा? URL में ब्राउज़र सीमाएँ होती हैं, और URL को ट्रिप करने से आप उन सीमाओं से टकरा सकते हैं।
लीव्ज

10
@RandalSchwartz टिल्ड है यूआरएल-सुरक्षित। RFC3986 से:unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
क्रालिक

3
चूँकि मुझे ,urlencoded होना चाहिए %2C, इसलिए मैं केवल वैरिएंट के ._- बजाय en.wikipedia.org/wiki/Base64#Variants_summary_table का उपयोग करने का सुझाव देता हूं जो अनुगामी रहता है =-_,
पॉल जूल

75

@joeshmo या एक सहायक फ़ंक्शन लिखने के बजाय, आप बस बेस 64 एन्कोडेड स्ट्रिंग को urlencode कर सकते हैं। यह आपके सहायक फ़ंक्शन के समान सटीक कार्य करेगा, लेकिन दो अतिरिक्त कार्यों की आवश्यकता के बिना।

$str = 'Some String';

$encoded = urlencode( base64_encode( $str ) );
$decoded = base64_decode( urldecode( $encoded ) );

2
परिणाम बिलकुल नहीं है। urlencode गैर-मान्य वर्णों को एन्कोड करने के लिए 3 वर्णों का उपयोग करता है और joeshmo का समाधान 1 का उपयोग करता है। यह एक बड़ा अंतर नहीं है, लेकिन यह अभी भी एक बेकार है।
जोसेफ बोर्कोवेक

1
@JosefBorkovec सच में? तो इसका मतलब यह भी होगा कि बाइट्स बेस 64 की एक ही संख्या-> url-> एन्कोडेड विभिन्न परिणामी लंबाई की एक किस्म हो सकती है, जबकि दूसरा समाधान एक पूर्वानुमान योग्य लेन देता है, है ना?
मानवतावादपी

@humanityANDpeace हाँ, urlencode एक चमकदार समाधान है क्योंकि यह कुछ बेस 64 स्ट्रिंग्स के आकार को ट्रिपल करता है। इनपुट से बड़ा आउटपुट होने के बाद भी आप बफर का पुन: उपयोग नहीं कर सकते।
नवीन

4
1 से 3 वर्णों का विस्तार औसतन 64 में से 3 वर्णों पर होता है, इसलिए यह 9% ओवरहेड (2 *
3/64

/चरित्र से सावधान रहें यदि आप इसे जीईटी पैरामीटर के रूप में नहीं, बल्कि URL में एक पथ के रूप में पास करते हैं। यदि आप /दोनों ओर से किसी और चीज़ से प्रतिस्थापित नहीं करते हैं तो यह आपका मार्ग बदल देगा
NeverEndingQueue

41

परिचयात्मक नोट मैं कुछ स्पष्टीकरण पोस्ट करने के लिए इच्छुक हूँ क्योंकि यहाँ कुछ उत्तर थोड़े भ्रामक थे (यदि गलत नहीं है)।

जवाब नहीं है , आप बस URL बेस स्ट्रिंग के भीतर एक बेस 64 एनकोडेड पैरामीटर पास नहीं कर सकते हैं क्योंकि प्लस चिह्न $ _GET वैश्विक सरणी के अंदर एक स्पेस में परिवर्तित हो जाते हैं। दूसरे शब्दों में, यदि आपने test.php भेजा है ? MyVar = stringwith + साइन इन करें

//test.php
print $_GET['myVar'];

परिणाम होगा:
stringwith sign

इसे हल करने का आसान तरीका यह है कि आप urlencode()अपने बेस64 स्ट्रिंग को क्वेरी स्ट्रिंग से जोड़ने के लिए +, =, और / वर्णों से बचने के लिए% ## कोड में जोड़ें। मसलन, urlencode("stringwith+sign")रिटर्नstringwith%2Bsign

जब आप कार्रवाई को संसाधित करते हैं, तो जब यह $ _GET वैश्विक पॉप्युलेट करता है, तो PHP क्वेरी स्ट्रिंग को स्वचालित रूप से डिकोड करने का ख्याल रखती है। उदाहरण के लिए, यदि मैंने test.php भेजा है ? MyVar = stringwith% 2Bsign को

//test.php
print $_GET['myVar'];

परिणाम होगा:
stringwith+sign

आप नहीं चाहते urldecode()कि लौटाए गए $ _GET स्ट्रिंग + के रिक्त स्थान में बदल जाएंगे।
दूसरे शब्दों में अगर मैंने एक ही टेस्ट भेजा है। php? MyVar = stringwith% 2Bsign to

//test.php
$string = urldecode($_GET['myVar']);
print $string;

परिणाम एक अप्रत्याशित है:
stringwith sign

यह rawurldecode()इनपुट के लिए सुरक्षित होगा , हालांकि, यह बेमानी होगा और इसलिए अनावश्यक है।


1
अच्छा उत्तर। यदि इस प्रश्न पर php को टैग किया गया है, तो आप इस साइट पर शुरू और समाप्त होने वाले टैग के बिना PHP कोड का उपयोग कर सकते हैं (सबसे अधिक बार यह सवाल के संदर्भ से स्पष्ट है)। यदि आप एक पंक्ति के अंत में दो रिक्त स्थान जोड़ते हैं <br>, तो आप इसे देखेंगे , इसलिए ज्यादा HTML टाइप करने की आवश्यकता नहीं है। मुझे उम्मीद है कि यह मदद करता है, मैंने आपके उत्तर को थोड़ा और भी बेहतर बनाने के लिए संपादित किया।
हकरे

यह उल्लेख करने के लिए धन्यवाद कि PHP आपके लिए URL को डिकोड करती है। जो मुझे खरगोश के छेद के अंदर गिरने से बचाता है।
कोकजेस्ट

शानदार उत्तर -> आप urldecode नहीं करना चाहते हैं () लौटे $ _GET स्ट्रिंग को + 's रिक्त स्थान में बदल दिया जाएगा। हालांकि, यह कच्चे माल के लिए सुरक्षित होगा () इनपुट,
मार्कोज़ेन

14

हां और ना।

बेस 64 का मूल चार्ट कुछ मामलों में URL में उपयोग किए जाने वाले पारंपरिक सम्मेलनों से टकरा सकता है। लेकिन कई बेस 64 कार्यान्वयन आपको URL को बेहतर तरीके से मिलान करने के लिए charset बदलने की अनुमति देते हैं या यहां तक ​​कि एक (जैसे पायथन urlsafe_b64encode()) के साथ आते हैं ।

आपके द्वारा सामना किया जा रहा एक अन्य मुद्दा URL की लंबाई या इसके बजाय - ऐसी सीमा का अभाव है। क्योंकि मानक किसी भी अधिकतम लंबाई को निर्दिष्ट नहीं करते हैं, ब्राउज़र, सर्वर, लाइब्रेरी और HTTP प्रोटोकॉल के साथ काम करने वाले अन्य सॉफ़्टवेयर इसकी स्वयं की सीमाओं को परिभाषित कर सकते हैं। आप इस लेख पर नज़र डाल सकते हैं: डब्ल्यूडब्ल्यूडब्ल्यू अक्सर पूछे जाने वाले प्रश्न: URL की अधिकतम लंबाई क्या है?


8

इसका बेस 64url एनकोड है जिसे आप ऊपर की ओर जेश्मो के कोड के विस्तार से देख सकते हैं।

function base64url_encode($data) {
return rtrim(strtr(base64_encode($data), '+/', '-_'), '=');
}

function base64url_decode($data) {
return base64_decode(str_pad(strtr($data, '-_', '+/'), strlen($data) % 4, '=', STR_PAD_RIGHT));
}

यह जावा के साथ एनकोडेड डेटा के लिए काम करता हैBase64.getUrlEncoder().withoutPadding().encodeToString()

4

मुझे नहीं लगता है कि यह सुरक्षित है क्योंकि उदाहरण के लिए "=" वर्ण का उपयोग कच्चे आधार 64 में किया जाता है और इसका उपयोग HTTP जीईटी में मानों से मापदंडों को अलग करने में भी किया जाता है।


1

सिद्धांत रूप में, हाँ, जब तक आप क्लाइंट या सर्वर के लिए अधिकतम url और / oor क्वेरी स्ट्रिंग लंबाई से अधिक नहीं होते हैं।

व्यवहार में, चीजें थोड़ी मुश्किल हो सकती हैं। उदाहरण के लिए, यह ASP.NET पर एक HttpRequestValidationException को ट्रिगर कर सकता है यदि मान "पर" होता है और आप अनुगामी "==" में छोड़ देते हैं।


आप +, /, या = वर्णों का उल्लेख नहीं करते हैं जो कुछ मामलों में यूआरएल को अमान्य बनाते हैं।
विल बर्कफोर्ड

0

Url सुरक्षित एनकोड के लिए, जैसे base64.urlsafe_b64encode(...)पायथन नीचे दिए गए कोड में, मेरे लिए 100% काम करता है

function base64UrlSafeEncode(string $input)
{
   return str_replace(['+', '/'], ['-', '_'], base64_encode($input));
}

-10

हां, यह हमेशा सुरक्षित है। बेशक base64 शामिल हैं: ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/= लेकिन एक base64 एन्कोडेड स्ट्रिंग आमतौर पर नहीं है ++एक रिक्त स्थान में परिवर्तित हो जाएगा, गलत डिकोड किए गए स्ट्रिंग में परिणाम। /एक सुरक्षित पैरामीटर जोड़ी में सुरक्षित है। =हमेशा बेस 64 एन्कोडेड स्ट्रिंग के अंत में होता है और सर्वर साइड =सीधे हल कर सकता है।


मुझे लगता है कि यह सही है, जैसा कि मैंने बेस 64 एनकोडिंग (बिना यूआरएल एन्कोडिंग) के साथ किए गए प्रयोग सफल रहे हैं, लेकिन मैं सोच रहा हूं कि क्या कोई दस्तावेज है जो आप इसे वापस प्रदान कर सकते हैं?
बीन

1
आप कहते हैं "हमेशा सुरक्षित" लेकिन फिर आप कहते हैं "आमतौर पर कोई + नहीं है"। तो अपने आप को विरोधाभास। + यदि आप इसे अपने बेस 64 स्ट्रिंग में करते हैं तो समस्याओं के कारण + साइन सीम।
निक हमिच
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.