केवल विश्वसनीय मोबाइल एप्लिकेशन के लिए REST API को कैसे सुरक्षित रखें


96

मैं यह कैसे सुनिश्चित करूं कि मेरा REST API केवल विश्वसनीय क्लाइंट्स द्वारा उत्पन्न अनुरोधों का जवाब देता है, मेरे मामले में मेरे स्वयं के मोबाइल एप्लिकेशन? मैं अन्य स्रोतों से आने वाले अवांछित अनुरोधों को रोकना चाहता हूं। मैं नहीं चाहता कि उपयोगकर्ता किसी सीरियल कुंजी को भरें या जो भी हो, यह दृश्यों के पीछे, स्थापना पर, और बिना किसी उपयोगकर्ता सहभागिता के आवश्यक होना चाहिए।

जहां तक ​​मुझे पता है, HTTPS केवल उस सर्वर को मान्य करने के लिए है, जिसके साथ आप संवाद कर रहे हैं कि यह कौन है। मैं डेटा को एन्क्रिप्ट करने के लिए HTTPS का उपयोग करने जा रहा हूँ।

क्या इसको मदद देने का कोई तरीका है?

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

एपीआई का उपयोग मोबाइल एप्लिकेशन के माध्यम से एक नया खाता पंजीकृत करने के लिए भी किया जाएगा।

अद्यतन 2: ऐसा लगता है कि इस के लिए कई उत्तर हैं, लेकिन मुझे ईमानदारी से पता नहीं है कि उत्तर के रूप में कौन से झंडे हैं। कुछ का कहना है कि यह किया जा सकता है, कुछ का कहना है कि यह नहीं हो सकता।


HTTPS SSL (और TLS) का उपयोग करता है। SSL / TLS का उपयोग क्लाइंट प्रमाणीकरण के साथ किया जा सकता है।
ATK

क्या आपका मतलब क्लाइंट साइड एसएसएल सर्टिफिकेट है? मुझे लगता है कि मैं वही तलाश कर रहा हूं, इसके अलावा मुझे कुछ पता नहीं है कि क्या मोबाइल एप्लिकेशन (एंड्रॉइड और आईओएस) में भी यह संभव है? ग्राहक प्रमाणपत्र कहां संग्रहीत किया जाएगा? डिवाइस स्टोरेज, मेमोरी?
सुपरसेल

एसएसएल केवल मोबाइल डिवाइस को प्रमाणित करेगा, न कि मोबाइल एप्लिकेशन को।
मोरों

@Supercell: मैं एक जवाब जोड़ देंगे
ATK

जवाबों:


48

आप नहीं कर सकते।

आप कभी भी किसी इकाई, किसी भी संस्था को सत्यापित नहीं कर सकते , चाहे वह व्यक्ति हो, हार्डवेयर क्लाइंट या सॉफ्टवेयर क्लाइंट हो। आप केवल यह सत्यापित कर सकते हैं कि वे आपको जो बता रहे हैं वह सही है, फिर ईमानदारी मानें

उदाहरण के लिए, Google को कैसे पता चलेगा कि मैं अपने जीमेल खाते में प्रवेश कर रहा हूं ? वे केवल मुझसे एक उपयोगकर्ता नाम और पासवर्ड के लिए पूछते हैं, इसे सत्यापित करते हैं , फिर ईमानदारी से मानते हैं क्योंकि उस जानकारी के अलावा और कौन होगा? कुछ बिंदु पर Google ने फैसला किया कि यह पर्याप्त और जोड़ा व्यवहार सत्यापन (विषम व्यवहार की तलाश में) नहीं है, लेकिन वह अभी भी व्यवहार करने के लिए व्यक्ति पर निर्भर है , फिर व्यवहार को मान्य कर रहा है

क्लाइंट को मान्य करने के साथ ठीक यही बात है। आप केवल क्लाइंट के व्यवहार को मान्य कर सकते हैं , लेकिन क्लाइंट को ही नहीं।

तो एसएसएल के साथ, आप सत्यापित कर सकते हैं कि ग्राहक के पास वैध प्रमाण पत्र है या नहीं, इसलिए कोई भी आपके ऐप को स्थापित कर सकता है, प्रमाणपत्र प्राप्त कर सकता है, फिर नया कोड चला सकता है।

तो सवाल यह है: यह इतना महत्वपूर्ण क्यों है? यदि यह एक वास्तविक चिंता है, तो मैं आपके एक मोटे ग्राहक की पसंद पर सवाल उठाऊंगा। शायद आपको एक वेब ऐप के साथ जाना चाहिए (ताकि आपको अपना एपीआई उजागर न करना पड़े)।

इसे भी देखें: एंड्रॉइड एप्लिकेशन के लिए एसएसएल प्रमाणपत्र सत्यापन को हराने

और: मोबाइल ऐप में क्लाइंट एसएसएल सर्टिफिकेट कितने सुरक्षित हैं?


1
मैंने हार्डवेयर पर क्लाइंट प्रमाणपत्र का उपयोग किया है जहां ओएस द्वारा एन्क्रिप्ट किए गए ड्राइव पर प्रमाण पत्र संग्रहीत किया गया था। लेकिन वहां भी, किसी ने भी इसे मूर्खतापूर्ण नहीं माना। लक्ष्य सिर्फ आकस्मिक उपयोगकर्ताओं के लिए कठिन बनाना था।
स्टीवन बर्नैप

1
@Morons: एक वेबऐप इसे हल करेगा, लेकिन हमें लगता है कि उपयोगकर्ता वेब एप की तुलना में मूल एप्लिकेशन का उपयोग करने की अधिक संभावना रखेंगे (कृपया हमारी धारणा गलत होने पर मुझे सही करें)। ऐसा क्यों महत्वपूर्ण है इसका कारण यह है कि एपीआई उपयोगकर्ता को हमारे डेटाबेस के कुछ हिस्सों तक पहुंच प्रदान करता है, जिसमें कई डेटा होते हैं जो हमने महीनों के काम के माध्यम से एकत्र किए थे। यह डेटा अन्य कंपनियों या उपयोगकर्ताओं को आसानी से अपने स्वयं के प्रयोजनों के लिए उपयोग कर सकता है। ग्राहकों को सुरक्षित किए बिना, हम यह नहीं जान पाएंगे कि इसका इस्तेमाल कौन कर रहा था (हमारे खिलाफ)।
सुपरसेल

6
एक वेबपेज समस्या हल नहीं करता है। यह किसी भी वेब-क्लाइंट क्लाइंट-साइड को संशोधित करने और जो भी आप चाहते हैं उसे करने के लिए काफी तुच्छ है।
स्टीवन बर्नैप

5
@ सुपरसेल आप किसी को डेटा नहीं दिखा सकते हैं और फिर उन्हें साझा करने से रोक सकते हैं। यदि आप कुछ डेटा नहीं चाहते हैं, तो आप उन्हें नहीं देते (इसे दिखाएं)।
मोरों

मैं सहमत हूं लेकिन विभिन्न कारणों से। यदि आप उपकरणों पर नियंत्रण रखते हैं, तो आप थोरा कर सकते हैं, rsa जैसे en.wikipedia.org/wiki/SecurID । लेकिन मोबाइल कुछ ऐसा नहीं है जिसे नियंत्रित किया जा सकता है (वे एक प्लगइन कुंजी या कुछ और की तरह लगाव को स्वीकार कर सकते हैं)।
imel96

31

मुझे यकीन है कि आप उपयोगकर्ता लॉगिन के साथ, और एसएसएल पर संचार के साथ सहज हैं, इसलिए मैं इस बात पर ध्यान केंद्रित करने जा रहा हूं कि यह प्रश्न का सबसे दिलचस्प हिस्सा क्या है: यह सुनिश्चित करने के लिए कि आपकी केवल-पढ़ने की क्रिया कैसे हो - जिसके लिए उपयोगकर्ता को प्रमाणित करने की आवश्यकता नहीं है - केवल आपके स्वयं के क्लाइंट ऐप्स से स्वीकार किए जाते हैं?

इससे पहले कि कुछ भी हो, नकारात्मक पक्ष यह है कि fNek ने पहले वाले उत्तर में संकेत दिया है - आपके क्लाइंट ऐप्स संभावित शत्रुतापूर्ण उपयोगकर्ताओं के हाथों में हैं। उनकी जांच की जा सकती है, उनके संचार का निरीक्षण किया गया, उनका कोड डिसाइड किया गया। मैं जो कुछ भी नहीं सुझाने जा रहा हूँ, वह आपको इस बात की गारंटी देगा कि कोई आपके क्लाइंट को रिवर्स-इंजीनियर नहीं करता है और आपके REST API का दुरुपयोग करता है। लेकिन यह किसी भी आकस्मिक प्रयासों के सामने एक बाधा डालनी चाहिए।

वैसे भी, एक आम दृष्टिकोण है:

  • क्लाइंट में एक रहस्य है
  • अनुरोध करते समय, यह रहस्यों के साथ अनुरोध मापदंडों को समाप्‍त कर देता है, और परिणाम को राख कर देता है
  • यह हैश अनुरोध के साथ भेजा जाता है, और सर्वर द्वारा जांचा जाता है

उदाहरण के लिए, एक GETअनुरोध की कल्पना करें/products/widgets

मान लें कि ग्राहक रहस्य "OH_HAI_I_IZ_SECRET" है

HTTP क्रिया, और URL और रहस्य को समाप्‍त करें:

GET/products/widgetsOH_HAI_I_IZ_SECRET

और उस का SHA-1 हैश लें:

4156023ce06aff06777bef3ecaf6d7fdb6ca4e02

फिर उस के साथ भेजें, इसलिए अनुरोध इस प्रकार होगा:

GET /products/widgets?hash=4156023ce06aff06777bef3ecaf6d7fdb6ca4e02

अंत में, किसी को कम से कम व्यक्तिगत अनुरोधों को दोहराने से रोकने के लिए, एक टाइमस्टैम्प भी लें, और उस पैरामीटर और हैश में जोड़ें। उदाहरण के लिए, यूनिक्स समय में अभी, 1384987891 है। इसे संघ में जोड़ें:

GET/products/widgetsOH_HAI_I_IZ_SECRET1384987891

हैश कि:

2774561d4e9eb37994d6d71e4f396b85af6cacd1

और भेज दें:

GET /products/widgets?time=1384987891&hash=2774561d4e9eb37994d6d71e4f396b85af6cacd1

सर्वर हैश की जाँच करेगा और यह भी सत्यापित करेगा कि टाइमस्टैम्प चालू है (उदाहरण के लिए 5 मिनट के भीतर घड़ियों के पूरी तरह से सिंक में न होने देने के लिए)

चेतावनी! चूंकि आप मोबाइल ऐप्स के बारे में बात कर रहे हैं, इसलिए एक निश्चित जोखिम है कि किसी के फोन में घड़ी गलत है। या टाइमजोन गलत। या कुछ और। हैश में समय जोड़ने से शायद कुछ वैध उपयोगकर्ता टूट जाएंगे, इसलिए सावधानी के साथ उस विचार का उपयोग करें।


6
यह हैशिंग तंत्र किसी भी प्रोग्रामर द्वारा समझा जा सकता है जब वह एपीके को असम्बद्ध करता है।
पुनीथ राज

8
@PunithRaj वास्तव में, मैंने उसे दूसरे पैराग्राफ में कवर किया। "कुछ भी नहीं है जो सुझाव देने जा रहा है, आपको यह गारंटी देने की अनुमति देगा कि कोई आपके ग्राहक को रिवर्स-इंजीनियर नहीं करता है और आपके REST API का दुरुपयोग करता है। लेकिन इसे किसी भी आकस्मिक प्रयासों के सामने एक बाधा डालनी चाहिए।"
कार्सन 63000

चेतावनी के लिए, सर्वर और मोबाइल पर UTC का उपयोग कर रहा हूँ, यह समस्या हल करता है, है ना?
शरीफ

@ Carson63000 - तो, ​​क्या कोई ठोस उपाय है? विशेष रूप से उपयोगकर्ता पंजीकरण एपीआई के लिए, जिसे सार्वजनिक रूप से खुला होना चाहिए (उपयोगकर्ता को वेब पर या मोबाइल ऐप पर लॉग इन करने से पहले पंजीकरण करने की आवश्यकता होती है) और हजारों नकली उपयोगकर्ता बनाने के लिए बॉट द्वारा लक्षित किया जा सकता है।
Tohid

17

रुचि रखने वाले किसी भी व्यक्ति के लिए, Android पर आप यह सत्यापित कर सकते हैं कि आपके द्वारा प्राप्त किया गया अनुरोध आपके ऐप से भेजा गया था।

संक्षेप में, जब आप अपने ऐप को Google पर अपलोड करते हैं, तो आप उस पर हस्ताक्षर करते हैं, एक अद्वितीय कुंजी के साथ जिसे आप (और Google) को ही जानते हैं।

सत्यापन प्रक्रिया इस तरह से होती है:

  1. आपका ऐप google को जाता है और ऑर्टिकल टोकन मांगता है
  2. आपका ऐप टोकन को सुरक्षित रूप से आपके बैक एंड पर भेजता है
    1. आपका बैक एंड Google पर जाता है और आपके ऐप से प्राप्त की गई टोकन की जाँच करता है।
    2. आपका बैक एंड तब चेक करता है कि क्या आपके ऐप में अद्वितीय कुंजी ने मैचों पर हस्ताक्षर किए हैं, यदि ऐसा नहीं है तो इसका मतलब है कि आपका ऐप नहीं था ...

पूरा ब्लॉग जो इसे समझाता है और इसे कैसे लागू किया जाए, यहां पाया जा सकता है: http://android-developers.blogspot.co.il/2013/01/verifying-back-end-calls-from-android.html


1
अच्छा जवाब, हालांकि एक दुर्भावनापूर्ण उपयोगकर्ता अभी भी पर्याप्त प्रयास के साथ एक ऐप को नकली कर सकता है। लेकिन कुछ भी सही मायने में सुरक्षित नहीं है, यह कोई बात नहीं है, बस जब बात है
mateos

1
IOS के लिए यह विकल्प है: लिंक The DeviceCheck API आपको यह सत्यापित करने देता है कि आपको प्राप्त टोकन एक प्रामाणिक Apple डिवाइस से आता है जिस पर आपका ऐप डाउनलोड किया गया है
Iwaz

इसके लिए खातों (ईमेल) की आवश्यकता है
user25

5

ठीक है, इसलिए मैं शुरू होने से पहले इसका उल्लेख करने लायक हूं कि अधिकांश अनुप्रयोगों के लिए यह अत्यधिक ओवरकिल है। ज्यादातर उपयोग के मामलों के लिए बस एक ही वैध प्रमाण पत्र और / या टोकन पर्याप्त से अधिक है। अगर इसमें कुछ भी करना मुश्किल है जैसे कि आपके ऐप को डिकम्पोज करना तो भी हैकर्स तब तक परेशान नहीं होंगे जब तक आप कुछ बहुत मूल्यवान डेटा प्रदान नहीं करते हैं। लेकिन हे, उस जवाब में मज़ा wheres?

तो आप जो कर सकते हैं वह कुछ हद तक असममित क्रिप्टोग्राफी सेट है जैसे कि डिजिटल हस्ताक्षर प्रोग्रामों पर हस्ताक्षर करने के लिए उपयोग किए जाते हैं। प्रत्येक ऐप में एक व्यक्तिगत प्रमाणपत्र हो सकता है जो एकल CA द्वारा जारी किया जाता है और जब आपका उपयोगकर्ता कनेक्ट होता है तो इसे सत्यापित किया जाता है। (या तो पहले पंजीकरण करते समय या पहली बार स्थापित करते समय) जब वह प्रमाणपत्र प्रमाणित हो जाता है, तो आप उस प्रमाणपत्र को एक दिए गए उपकरण पहचानकर्ता के लिए मान्य करके अपना आवेदन सुरक्षित कर सकते हैं (जैसे कि एंड्रॉइड आईडी )


5

जैसा कि @Morons ने अपने उत्तर में उल्लेख किया है, कनेक्शन के दूसरे छोर पर इकाई को सत्यापित करना बहुत मुश्किल है।

कुछ स्तर की प्रामाणिकता प्रदान करने का सबसे सरल तरीका यह है कि सर्वर कुछ रहस्य की जांच करे, जो केवल वास्तविक इकाई को पता होगा। एक उपयोगकर्ता के लिए, वह एक उपयोगकर्ता नाम और एक पासवर्ड हो सकता है। सॉफ्टवेयर के एक टुकड़े के लिए जहां कोई उपयोगकर्ता नहीं है आप एक गुप्त एम्बेड कर सकते हैं।

इन दृष्टिकोणों के साथ समस्या यह है कि आपको क्लाइंट में कुछ भरोसा रखना होगा। अगर कोई आपके ऐप को रिवर्स करता है या आपका पासवर्ड चुराता है तो वे आपके होने का दिखावा कर सकते हैं।

आप निष्पादन योग्य में गुप्त जानकारी को निकालने के लिए इसे कठिन बनाने के लिए कदम उठा सकते हैं। ProGuard जैसे उपकरण जो कि Java के लिए एक obfuscator है, इससे मदद मिल सकती है, मुझे अन्य भाषाओं में obfuscation के बारे में उतना नहीं पता है, लेकिन संभवतः इसी तरह के टूल भी हैं। टीएलएस कनेक्शन का उपयोग करने से आपके ट्रैफ़िक पर लोगों की छींटाकशी को रोकने में मदद मिलती है, लेकिन MITM हमले को नहीं रोकता है। पिनिंग उस मुद्दे को संबोधित करने में मदद कर सकता है।

मैं क्रिटिकलब्लू (पूर्ण प्रकटीकरण) नामक कंपनी के लिए काम करता हूं, जिसके पास अप्रोव नामक एक उत्पाद है जो विश्वास की इस समस्या को दूर करने की कोशिश करता है। यह वर्तमान में एंड्रॉइड / आईओएस के लिए काम करता है और क्लाइंट सर्वर की अखंडता की जांच करने के लिए हमारे सर्वर के लिए एक तंत्र प्रदान करता है। यह एक यादृच्छिक चुनौती की प्रतिक्रिया की गणना करने के लिए क्लाइंट को प्राप्त करने के द्वारा करता है। क्लाइंट को इंस्टॉल किए गए ऐप पैकेज की विशेषताओं का उपयोग करके प्रतिक्रिया की गणना करना है जो नकली के लिए कठिन हैं और इसमें कुछ परिष्कृत एंटी-टैम्पर तंत्र शामिल हैं।

यह एक टोकन देता है जिसे आप फिर अपने एपीआई को प्रामाणिकता के प्रमाण के रूप में भेज सकते हैं।

इस दृष्टिकोण के साथ महत्वपूर्ण अंतर यह है कि यद्यपि क्लाइंट पर प्रामाणिकता जांच को अक्षम करना संभव होगा, यदि आपने ऐसा किया है तो आपको सर्वर के साथ अपने ऐप को सत्यापित करने के लिए प्रमाणीकरण टोकन नहीं मिलेगा। लाइब्रेरी को कसकर निष्पादन योग्य विशेषताओं के साथ युग्मित किया जाता है, यह भीतर है, इसलिए इसे नकली ऐप में एम्बेड करना और यह काम करना बहुत मुश्किल होगा।

किसी भी एपीआई डेवलपर को लागत / लाभ का विश्लेषण करना होगा ताकि यह तय किया जा सके कि यह संभव है कि कोई व्यक्ति अपना एपीआई हैक करने की कोशिश करे और यह कितना महंगा हो सकता है। आवेदन में एक साधारण गुप्त जांच तुच्छ हमलों को रोकती है, लेकिन एक अधिक निर्धारित हमलावर के खिलाफ खुद को बचाने के लिए संभवतः बहुत अधिक जटिल और संभावित रूप से घातक है।


0

एसएसएल संचार चैनल को सुरक्षित करेगा।

सफल लॉगिन एन्क्रिप्टेड कनेक्शन पर एक प्रमाणीकरण टोकन जारी करेगा।

बाद के सभी अनुरोधों में प्रमाणीकरण टोकन आपके REST API को पास कर दिया जाएगा।


1
मैंने कुछ अतिरिक्त जानकारी जोड़ी है। मैं एक्सेस टोकन के साथ आपके द्वारा उल्लिखित प्रमाणीकरण करने की योजना बना रहा था। REST API को उपयोगकर्ता को केवल विशिष्ट कार्यों के लिए लॉग इन करने की आवश्यकता नहीं है। दोनों ही मामलों में, क्लाइंट को हस्ताक्षरित / भरोसेमंद होना चाहिए।
सुपरसेल

मुझे देशी मोबाइल विकास के बारे में ज्यादा जानकारी नहीं है, लेकिन क्या आपका मोबाइल एप्लिकेशन REST API को मोबाइल नंबर प्रदान कर सकता है? जब मैं अपने एंड्रॉइड फोन पर एप्लिकेशन इंस्टॉल करता हूं, तो मुझे अक्सर एप्लिकेशन को कुछ अनुमतियाँ देने के लिए कहा जाता है। यदि आप सुरक्षित कनेक्शन पर प्रत्येक अनुरोध के साथ एक मोबाइल नंबर भेज सकते हैं, तो आप अज्ञात मोबाइल नंबर के साथ सभी अनुरोधों को अस्वीकार कर सकते हैं। बस यहाँ जोर से सोच ...
कोडार्ट

यह काम कर सकता है, लेकिन इसके लिए उपयोगकर्ता को लॉग इन करना होगा और उपयोगकर्ता खाते से बंधी संख्या होगी। अन्यथा सर्वर के पास संख्या को सत्यापित करने के लिए कुछ भी नहीं होगा।
सुपरसेल

आप अपना मोबाइल एप्लिकेशन कैसे स्थापित करेंगे?
कोडर्ट

वे ऐप स्टोर्स (Google, Apple, Microsoft)
Supercell

0

यह बहुत सुरक्षित नहीं होगा, लेकिन आप किसी प्रकार का गुप्त कोड या यहां तक ​​कि एक dgital हस्ताक्षर भी जोड़ सकते हैं। डाउनसाइड: इसे ऐप में शामिल किया जाना चाहिए, जो आपको पता है कि आप क्या करते हैं, इसे प्राप्त करना आसान है।


0

जहां तक ​​मुझे पता है, HTTPS केवल उस सर्वर को मान्य करने के लिए है, जिसके साथ आप संवाद कर रहे हैं कि यह कौन है।

वास्तव में, आप क्लाइंट और सर्वर दोनों को प्रमाणित करने के लिए एसएसएल का उपयोग कर सकते हैं। या, अलग तरह से कहा गया है, "हाँ, आप क्लाइंट प्रमाणपत्र का उपयोग कर सकते हैं"।

आपको इसकी आवश्यकता होगी ...

  • मोबाइल डिवाइस में क्लाइंट प्रमाणपत्र कैसे निर्दिष्ट करें, यह निर्धारित करने के लिए आप जिस एसएसएल लाइब्रेरी का उपयोग कर रहे हैं, उसे देखें।
  • कोड लिखें या अपने HTTPS सर्वर को कॉन्फ़िगर करें ताकि यह केवल विश्वसनीय, पंजीकृत ग्राहकों से कनेक्शन स्वीकार करे।
  • अपने सर्वर में विश्वसनीय क्लाइंट प्रमाणपत्र जोड़ने के लिए एक तंत्र के साथ आओ
  • अपने सर्वर से नो-अब-विश्वसनीय क्लाइंट सर्टिफिकेट को हटाने के लिए एक तंत्र के साथ आओ

आप जहां चाहें वहां मोबाइल एप्लिकेशन को प्रमाण पत्र स्टोर कर सकते हैं। चूंकि आप इसे एप्लिकेशन-विशिष्ट प्रमाणीकरण चाहते हैं, इसलिए आपको एक संरक्षित डिस्क स्थान में प्रमाण पत्र को संग्रहीत करने पर विचार करना चाहिए (एंड्रॉइड पर, आप अपने SQLite डेटाबेस में "कॉन्फ़िगर" तालिका बना सकते हैं, और आपके प्रमाणपत्र के लिए एक पंक्ति और आपकी निजी कुंजी के लिए एक और) ।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.