RS256 बनाम HS256: क्या अंतर है?


254

मैं अपने वेब ऐप में प्रमाणीकरण को संभालने के लिए Auth0 का उपयोग कर रहा हूं। मैं ASP.NET Core v1.0.0 और कोणीय 2 rc5 का उपयोग कर रहा हूं और मुझे सामान्य रूप से प्रमाणीकरण / सुरक्षा के बारे में ज्यादा जानकारी नहीं है।

में ASP.NET कोर वेब एपीआई के लिए Auth0 डॉक्स , वहाँ जेडब्ल्यूटी एल्गोरिथ्म RS256 और HS256 होने के लिए दो विकल्प हैं। यह एक गूंगा प्रश्न हो सकता है लेकिन:

RS256 और HS256 में क्या अंतर है? कुछ उपयोग के मामले क्या हैं (यदि लागू हो)?


मुझे सर्वर-साइड एप्लिकेशन ट्यूटोरियल freakyjolly.com/
कोड जासूस

जवाबों:


437

दोनों विकल्प पहचानकर्ता को JWT पर हस्ताक्षर करने के लिए किस एल्गोरिथ्म का उपयोग करते हैं । हस्ताक्षर एक क्रिप्टोग्राफ़िक ऑपरेशन है जो एक "हस्ताक्षर" (JWT का हिस्सा) उत्पन्न करता है कि टोकन प्राप्त करने वाला यह सुनिश्चित करने के लिए मान्य कर सकता है कि टोकन के साथ छेड़छाड़ नहीं की गई है।

  • RS256 ( SHA-256 के साथ RSA हस्ताक्षर ) एक असममित एल्गोरिथ्म है , और यह एक सार्वजनिक / निजी कुंजी जोड़ी का उपयोग करता है: पहचान प्रदाता के पास हस्ताक्षर बनाने के लिए उपयोग की जाने वाली एक निजी (गुप्त) कुंजी होती है, और JWT के उपभोक्ता को एक सार्वजनिक कुंजी मिलती है हस्ताक्षर को मान्य करने के लिए। चूंकि सार्वजनिक कुंजी, निजी कुंजी के विपरीत, को सुरक्षित रखने की आवश्यकता नहीं है, अधिकांश पहचान प्रदाता उपभोक्ताओं को इसे प्राप्त करने और उपयोग करने के लिए आसानी से उपलब्ध कराते हैं (आमतौर पर मेटाडेटा URL के माध्यम से)।

  • दूसरी ओर, HS256 ( SHA-256 के साथ HMAC ), हैशिंग फ़ंक्शन का एक संयोजन और एक (गुप्त) कुंजी शामिल है, जो कि हैश उत्पन्न करने के लिए उपयोग की जाने वाली दो पार्टियों के बीच साझा की जाती है जो हस्ताक्षर के रूप में काम करेगी। चूंकि हस्ताक्षर बनाने के लिए और इसे मान्य करने के लिए एक ही कुंजी का उपयोग किया जाता है, इसलिए यह सुनिश्चित करने के लिए ध्यान रखा जाना चाहिए कि कुंजी समझौता नहीं किया गया है।

यदि आप JWTs का उपभोग करने वाले एप्लिकेशन को विकसित कर रहे हैं, तो आप सुरक्षित रूप से HS256 का उपयोग कर सकते हैं, क्योंकि आपके पास गुप्त कुंजियों का उपयोग करने वाले पर नियंत्रण होगा। यदि, दूसरी ओर, आपके पास ग्राहक पर नियंत्रण नहीं है, या आपके पास गुप्त कुंजी हासिल करने का कोई तरीका नहीं है, तो RS256 एक बेहतर फिट होगा, क्योंकि उपभोक्ता को केवल सार्वजनिक (साझा) कुंजी जानने की आवश्यकता होती है।

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

Auth0 OIDC, SAML और WS-Fed प्रोटोकॉल के लिए मेटाडेटा समापन बिंदु प्रदान करता है, जहां सार्वजनिक कुंजियों को पुनर्प्राप्त किया जा सकता है। आप एक ग्राहक की "उन्नत सेटिंग्स" के तहत उन समापन बिंदुओं को देख सकते हैं।

OIDC मेटाडेटा समापन बिंदु, उदाहरण के लिए, का रूप लेता है https://{account domain}/.well-known/openid-configuration। यदि आप उस URL पर ब्राउज़ करते हैं, तो आपको एक JSON ऑब्जेक्ट दिखाई देगा https://{account domain}/.well-known/jwks.json, जिसमें अकाउंट की सार्वजनिक कुंजी (या कुंजियाँ) हैं।

यदि आप RS256 नमूनों को देखते हैं, तो आप देखेंगे कि आपको सार्वजनिक कुंजी को कहीं भी कॉन्फ़िगर करने की आवश्यकता नहीं है: यह फ्रेमवर्क द्वारा स्वचालित रूप से पुनर्प्राप्त किया जाता है।


46
NB जब rs256 का उपयोग कर रहा है - कई पुस्तकालयों में एक सुरक्षा जोखिम है (या था) जिसने टोकन को यह निर्धारित करने की अनुमति दी कि किस एल्गोरिदम का उपयोग करना है। अनिवार्य रूप से हमलावर सार्वजनिक rs256 कुंजी को hs256 एन्कोडिंग के साथ इस्तेमाल कर सकता है ताकि यह गुप्त कुंजी हो। तो सुनिश्चित करें कि आपके पुस्तकालय में यह व्यवहार नहीं है!
एलेक्सफॉक्सगिल

7
एक छोटा सुधार, "HS256 (SHA-256 के साथ HMAC), दूसरी ओर, एक सममित एल्गोरिथ्म है" - HMAC एक सममित-कुंजी एल्गोरिथ्म का उपयोग नहीं करता है (जो आपको इसकी परिभाषा के लिए हस्ताक्षर एन्क्रिप्ट और डिक्रिप्ट करने की अनुमति देगा)। यह एक क्रिप्टोग्राफ़िक हैश फ़ंक्शन और HMAC के नीचे एक गुप्त क्रिप्टोग्राफ़िक कुंजी का उपयोग करता है । तात्पर्य यह है कि संदेश पर हैश (वन वे फंक्शन) की गणना एक गुप्त गुप्त कुंजी के साथ की जाती है।
किकोज

1
Google के साथ उदाहरण: accounts.google.com/.well-ogn/openid-configuration पर जाएं और jwks_uri को देखें; इसके बाद आप googleapis.com/oauth2/v3/certs पर जाएं जहां आप चाबियां पा सकते हैं। तो आपको बस इसके बच्चे द्वारा अच्छी कुंजी को पुनः प्राप्त करना होगा।
डेनिस TRUFFAUT

वर्थ नोटिंग कि HS256 दो पक्षों के बीच एक कुंजी साझा करता है जो इस एल्गोरिथ्म को एक एक्सेस_टोकेन में कई दर्शकों का समर्थन करने में असमर्थ बनाता है, जबकि RS256 कई दर्शकों का समर्थन कर सकता है। यह Auth0 जैसे आइडेंटिटी क्लाइंट्स के लिए मायने रखता है, जो केवल कॉन्फ़िगरेशन_token का उपयोग करते हुए / userinfo समापन बिंदु के लिए एक अनुरोध की अनुमति देता है अगर कॉन्फ़िगरेशन RS256 है, क्योंकि उन्हें ऑडिशन के रूप में आपके एपीआई डोमेन के साथ-साथ अपने SSL0 डोमेन का समर्थन करने के लिए इस टोकन की आवश्यकता होती है।
jezpez

94

क्रिप्टोग्राफी में दो प्रकार के एल्गोरिदम का उपयोग किया जाता है:

सममित एल्गोरिदम

डेटा को एन्क्रिप्ट करने के लिए सिंगल की का इस्तेमाल किया जाता है। जब कुंजी के साथ एन्क्रिप्ट किया जाता है, तो डेटा को उसी कुंजी का उपयोग करके डिक्रिप्ट किया जा सकता है। यदि, उदाहरण के लिए, मैरी कुंजी "माय-सीक्रेट" का उपयोग करके एक संदेश एन्क्रिप्ट करती है और जॉन को भेजती है, तो वह उसी कुंजी "माय-सीक्रेट" के साथ संदेश को सही ढंग से डिक्रिप्ट कर सकेगी।

असममित एल्गोरिदम

संदेशों को एन्क्रिप्ट और डिक्रिप्ट करने के लिए दो कुंजी का उपयोग किया जाता है। जबकि एक कुंजी (सार्वजनिक) का उपयोग संदेश को एन्क्रिप्ट करने के लिए किया जाता है, दूसरी कुंजी (निजी) का उपयोग केवल इसे डिक्रिप्ट करने के लिए किया जा सकता है। इसलिए, जॉन सार्वजनिक और निजी दोनों प्रकार की कुंजी उत्पन्न कर सकता है, फिर अपने संदेश को एन्क्रिप्ट करने के लिए मैरी को केवल सार्वजनिक कुंजी भेजें। संदेश केवल निजी कुंजी का उपयोग करके डिक्रिप्ट किया जा सकता है।

HS256 और RS256 परिदृश्य

इन एल्गोरिदम का उपयोग डेटा को एन्क्रिप्ट / डिक्रिप्ट करने के लिए नहीं किया जाता है। बल्कि उनका उपयोग डेटा की उत्पत्ति या प्रामाणिकता को सत्यापित करने के लिए किया जाता है। जब मैरी को झोन के लिए एक खुला संदेश भेजने की आवश्यकता होती है और उन्हें यह सत्यापित करने की आवश्यकता होती है कि संदेश निश्चित रूप से मैरी से है, HS256 या RS256 का उपयोग किया जा सकता है।

HS256 किसी एक कुंजी का उपयोग करके दिए गए डेटा के नमूने के लिए एक हस्ताक्षर बना सकता है। जब संदेश हस्ताक्षर के साथ प्रेषित होता है, तो प्राप्त करने वाला पक्ष यह सत्यापित करने के लिए उसी कुंजी का उपयोग कर सकता है कि हस्ताक्षर संदेश से मेल खाता है।

RS256 समान करने के लिए कुंजियों की जोड़ी का उपयोग करता है। एक हस्ताक्षर केवल निजी कुंजी का उपयोग करके उत्पन्न किया जा सकता है। और सार्वजनिक कुंजी का उपयोग हस्ताक्षर को सत्यापित करने के लिए किया जाना है। इस परिदृश्य में, भले ही जैक को सार्वजनिक कुंजी मिल जाए, वह मैरी को प्रतिरूपित करने के लिए एक हस्ताक्षर के साथ एक स्पूफ संदेश नहीं बना सकता है।


38

प्रदर्शन में अंतर है।

सीधे शब्दों में कहें HS256तो RS256सत्यापन के लिए तेजी से परिमाण के बारे में 1 आदेश है लेकिन RS256जारी करने (हस्ताक्षर करने) की तुलना में तेजी से परिमाण के लगभग 2 आदेश ।

 640,251  91,464.3 ops/s
  86,123  12,303.3 ops/s (RS256 verify)
   7,046   1,006.5 ops/s (RS256 sign)

वास्तविक संख्याओं में मत उलझो, उन्हें एक दूसरे के सम्मान के साथ सोचो।

[Program.cs]

class Program
{
    static void Main(string[] args)
    {
        foreach (var duration in new[] { 1, 3, 5, 7 })
        {
            var t = TimeSpan.FromSeconds(duration);

            byte[] publicKey, privateKey;

            using (var rsa = new RSACryptoServiceProvider())
            {
                publicKey = rsa.ExportCspBlob(false);
                privateKey = rsa.ExportCspBlob(true);
            }

            byte[] key = new byte[64];

            using (var rng = new RNGCryptoServiceProvider())
            {
                rng.GetBytes(key);
            }

            var s1 = new Stopwatch();
            var n1 = 0;

            using (var hs256 = new HMACSHA256(key))
            {
                while (s1.Elapsed < t)
                {
                    s1.Start();
                    var hash = hs256.ComputeHash(privateKey);
                    s1.Stop();
                    n1++;
                }
            }

            byte[] sign;

            using (var rsa = new RSACryptoServiceProvider())
            {
                rsa.ImportCspBlob(privateKey);

                sign = rsa.SignData(privateKey, "SHA256");
            }

            var s2 = new Stopwatch();
            var n2 = 0;

            using (var rsa = new RSACryptoServiceProvider())
            {
                rsa.ImportCspBlob(publicKey);

                while (s2.Elapsed < t)
                {
                    s2.Start();
                    var success = rsa.VerifyData(privateKey, "SHA256", sign);
                    s2.Stop();
                    n2++;
                }
            }

            var s3 = new Stopwatch();
            var n3 = 0;

            using (var rsa = new RSACryptoServiceProvider())
            {
                rsa.ImportCspBlob(privateKey);

                while (s3.Elapsed < t)
                {
                    s3.Start();
                    rsa.SignData(privateKey, "SHA256");
                    s3.Stop();
                    n3++;
                }
            }

            Console.WriteLine($"{s1.Elapsed.TotalSeconds:0} {n1,7:N0} {n1 / s1.Elapsed.TotalSeconds,9:N1} ops/s");
            Console.WriteLine($"{s2.Elapsed.TotalSeconds:0} {n2,7:N0} {n2 / s2.Elapsed.TotalSeconds,9:N1} ops/s");
            Console.WriteLine($"{s3.Elapsed.TotalSeconds:0} {n3,7:N0} {n3 / s3.Elapsed.TotalSeconds,9:N1} ops/s");

            Console.WriteLine($"RS256 is {(n1 / s1.Elapsed.TotalSeconds) / (n2 / s2.Elapsed.TotalSeconds),9:N1}x slower (verify)");
            Console.WriteLine($"RS256 is {(n1 / s1.Elapsed.TotalSeconds) / (n3 / s3.Elapsed.TotalSeconds),9:N1}x slower (issue)");

            // RS256 is about 7.5x slower, but it can still do over 10K ops per sec.
        }
    }
}

ये महत्वपूर्ण संख्याएँ हैं। धन्यवाद। मुझे लगता है कि एन्क्रिप्शन को कम या ज्यादा पारदर्शी wrt थ्रूपुट माना जाता है, लेकिन आपके शोध का अर्थ है कि R256 का उपयोग करना अंतर-संचार संचार पर हस्ताक्षर करने के लिए प्रति मिनट 1 एमएस जोड़ता है।
मैथ्यू मार्क मिलर

1
@MatthewMarkMiller ध्यान रखें कि वे उपयोग में समान नहीं हैं। उनकी अलग विशेषताएं हैं। RS256 असममित है और इसलिए क्लाइंट / सर्वर शैली संचार में जहां आप केवल सार्वजनिक कुंजी साझा करते हैं, यह एक बेहतर विकल्प है। HS256 को उस कुंजी को साझा करने की आवश्यकता है जो हस्ताक्षर और सत्यापन दोनों कर सकती है - केवल तभी उपयोगी है जब आप दोनों पक्षों पर भरोसा करते हैं या किसी भी चीज़ को डिक्रिप्ट करने के लिए किसी एक पक्ष की आवश्यकता नहीं है।
रोब इवांस

7
@RobEvans हाँ, यहाँ प्रदर्शन संख्या पर लटका नहीं है। अपनी समस्या का सही समाधान उठाओ। यह सिर्फ एक अवलोकन है, RS256 पर HS256 के पक्ष में करने की सिफारिश नहीं है। आपको यह निर्णय अपने संदर्भ के आधार पर करना चाहिए।
जॉन लेडिग्रेन

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

0

लघु उत्तर, OAuth2 के लिए विशिष्ट,

  • टोकन हस्ताक्षर उत्पन्न करने के लिए HS256 उपयोगकर्ता ग्राहक रहस्य और बैक-एंड में टोकन को मान्य करने के लिए उसी रहस्य की आवश्यकता होती है। तो आपके पास हस्ताक्षर को सत्यापित करने के लिए आपके बैक-एंड सर्वर में उस रहस्य की एक प्रति होनी चाहिए।
  • RS256 टोकन को साइन करने के लिए सार्वजनिक कुंजी एन्क्रिप्शन का उपयोग करें। सिग्नेचर (हैश) निजी कुंजी का उपयोग करके बनाएगा और यह सार्वजनिक कुंजी का उपयोग करके सत्यापित कर सकता है। तो, बैक-एंड सर्वर में स्टोर करने के लिए निजी कुंजी या क्लाइंट सीक्रेट की कोई आवश्यकता नहीं है, लेकिन बैक-एंड सर्वर आपके किरायेदार ( https: // [tenant] / /well- जानी/openid में ओपेनड कॉन्फ़िगरेशन url से सार्वजनिक कुंजी लाएगा। -configuration ) टोकन को सत्यापित करने के लिए। Access_toekn के अंदर KID पैरामीटर ओपन-कॉन्फ़िगरेशन से सही कुंजी (सार्वजनिक) का पता लगाने के लिए उपयोग करेगा।
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.