क्या कोई SHA-256 जावास्क्रिप्ट कार्यान्वयन हैं जिन्हें आमतौर पर भरोसेमंद माना जाता है?


95

मैं एक फोरम के लिए एक लॉगिन लिख रहा हूं, और इसे सर्वर पर भेजने से पहले जावास्क्रिप्ट में पासवर्ड क्लाइंट साइड को हैश करने की आवश्यकता है। मुझे यह पता लगाने में कठिनाई हो रही है कि कौन सा SHA-256 कार्यान्वयन मैं वास्तव में भरोसा कर सकता हूं। मैं उम्मीद कर रहा था कि किसी तरह की आधिकारिक पटकथा हो, जिसका सभी लोग उपयोग करें, लेकिन मैं सभी परियोजनाओं को अपने स्वयं के कार्यान्वयन के साथ पा रहा हूं।

मुझे लगता है कि अन्य लोगों के क्रिप्टो का उपयोग करना हमेशा विश्वास की एक छलांग है जब तक कि आप इसे स्वयं की समीक्षा करने के लिए योग्य न हों, और यह कि "भरोसेमंद" की कोई सार्वभौमिक परिभाषा नहीं है, लेकिन यह कुछ सामान्य और महत्वपूर्ण जैसा लगता है कि किसी तरह का होना चाहिए क्या उपयोग करना है इस पर आम सहमति। क्या मैं सिर्फ भोला हूँ?

संपादित करें क्योंकि यह टिप्पणियों में बहुत ऊपर आता है: हां, हम सर्वर पर फिर से अधिक कठोर हैश करते हैं। क्लाइंट साइड हैशिंग का अंतिम परिणाम नहीं है जिसे हम डेटाबेस में सहेजते हैं। ग्राहक पक्ष हैशिंग इसलिए है क्योंकि मानव ग्राहक इसका अनुरोध करता है। उन्होंने कोई खास वजह नहीं बताई है, शायद उन्हें ओवरकिल पसंद है।


9
विषय से हटने के लिए नहीं, लेकिन आप क्लाइंट की तरफ पासवर्ड क्यों डाल रहे हैं?
स्टीव

5
@ddyer पास भी नहीं है। "अपना स्वयं का रोल न करें" अपने खुद के एल्गोरिथ्म का आविष्कार करने के लिए लागू होता है, एक एल्गोरिथ्म के अपने कार्यान्वयन को लिखते हुए , क्रिप्टो एल्गोरिदम के शीर्ष पर अपने स्वयं के प्रोटोकॉल को विकसित करना, या उच्च-स्तरीय एब्सट्रैक्शन के रूप में उपलब्ध के रूप में उपयोग करके ऊपर कुछ भी बहुत कुछ है। यदि आपको लगता है कि आप सुरक्षित कोर से चिपके रहेंगे, और केवल गोंद कोड लिखेंगे, तो आपके पास एक बुरा समय होगा।
स्टीफन टॉसेट

26
यदि आप एक चुनौती / प्रतिक्रिया प्रोटोकॉल के बिना हैशेड पासवर्ड का उपयोग करते हैं, तो हैशेड पासवर्ड पासवर्ड है और यह स्पष्ट पाठ में पासवर्ड को प्रसारित करने के समान है।
ddyer

26
@ddyer विशेष रूप से हमारी साइट के लिए नहीं, तो अन्य सभी साइटों के लिए उपयोगकर्ता के प्लेटेक्स्ट पासवर्ड की सुरक्षा में कुछ मूल्य है, जो वे इसका उपयोग कर सकते हैं। यह एक आसान समाधान है जो शायद हमारी मदद नहीं करेगा लेकिन यदि हम कहीं पर पेंच करते हैं तो संभवतः उपयोगकर्ता की मदद कर सकते हैं। और जैसा मैंने कहा, ग्राहक अनुरोध, मैं इसके बारे में कुछ नहीं कर सकता, भले ही मैं चाहता था।
jono

4
@Anorov मैं अपने दिमाग को बदलने के लिए खुला से अधिक हूं :) लेकिन इस मामले में, मैं वास्तव में नहीं समझता कि आपकी बात कैसे लागू होती है। हमारे पास दो बार पासवर्ड है: एक बार साधारण SHA-256 के साथ क्लाइंट की ओर, और एक बार सर्वर पर कुछ और मांग के साथ। पहला MITM या इसी तरह के मामले में प्लेनटेक्स्ट की सुरक्षा के लिए, और दूसरा ब्रूट प्रोटेक्शन के लिए। यहां तक ​​कि अगर आपको डेटाबेस और एडमिन हैश की पकड़ मिली है, तो आप लॉगिन को सीधे सत्यापित करने के लिए उपयोग नहीं कर सकते।
जोनो

जवाबों:


111

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

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

इसलिए आपकी सुरक्षा अब और खराब हो गई है क्योंकि आपने निर्णय लिया है कि पहले जो एक विश्वसनीय योजना थी उसमें अपने सुधारों को जोड़ें


31
यदि आपके पास फिर से सर्वर पर हैश है, तो यह अभ्यास पूरी तरह से वैध है।
निक ब्रंट

13
@NickBrunt यदि आपके पास सर्वर पर हैश है तो आप ट्रांसमिट किए हुए पासवर्ड को सेव नहीं कर रहे हैं, लेकिन आपने पासवर्ड को हैश ट्रांसमिट करने के विपरीत मूल पासवर्ड को ट्रांसमिट करने से परे कोई सुरक्षा नहीं जोड़ी है, क्योंकि किसी भी स्थिति में आप जो ट्रांसमिट कर रहे हैं। असली पासवर्ड।
tylerl

54
यह सच है, लेकिन यह एक पासवर्ड भेजने से भी बदतर नहीं है जो संभवतः इंटरनेट पर कहीं और इस्तेमाल किया जाता है।
निक ब्रंट

15
मैं @NickBrunt से सहमत हूं। यह बेहतर है अगर हमलावर एक यादृच्छिक हैश स्ट्रिंग पढ़ता है जो मूल पासवर्ड के बजाय केवल इस विशेष ऐप के साथ फिट हो सकता है जो कई स्थानों पर उपयोग किया जा सकता है।
ऐब्सबिस

12
मुझे क्लाइंट-साइड हैशिंग का उपयोग करने की आवश्यकता है क्योंकि मैं नहीं चाहता कि सर्वर कभी भी उपयोगकर्ता के प्लेनटेक्स्ट पासवर्ड को देख सके। मेरे द्वारा प्रदान की जा रही सेवा, लेकिन उपयोगकर्ता की ओर से अतिरिक्त सुरक्षा के लिए नहीं। मैं न केवल उपयोगकर्ता के हैश को लगातार नमक (लगातार प्रति उपयोगकर्ता, विश्व स्तर पर) के साथ नमकीन बचा रहा हूं, बल्कि इसे हर सत्र में एक यादृच्छिक सत्र नमक के साथ फिर से हैशिंग कर रहा हूं जो कि सूँघने के खिलाफ नेटवर्क पर थोड़ी अतिरिक्त सुरक्षा प्रदान करता है। यदि सर्वर समझौता हो जाता है तो यह गेम खत्म हो जाता है, लेकिन यह किसी भी चीज के लिए सही नहीं है, वैसे भी P2P वैसे भी।
हतागाशिरा

49

पर https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/digest मैं इस टुकड़ा आंतरिक js मॉड्यूल का उपयोग करता है पाया:

async function sha256(message) {
    // encode as UTF-8
    const msgBuffer = new TextEncoder('utf-8').encode(message);                    

    // hash the message
    const hashBuffer = await crypto.subtle.digest('SHA-256', msgBuffer);

    // convert ArrayBuffer to Array
    const hashArray = Array.from(new Uint8Array(hashBuffer));

    // convert bytes to hex string                  
    const hashHex = hashArray.map(b => ('00' + b.toString(16)).slice(-2)).join('');
    return hashHex;
}

ध्यान दें कि आपके स्थानीय विकास के लिए उदाहरण के लिए या crypto.subtleकेवल आपके लिए उपलब्ध इस लाइन को अपने साथ जोड़ने की आवश्यकता है : httpslocalhostpython3 -m http.server/etc/hosts0.0.0.0 localhost

रिबूट - और आप localhost:8000काम करने के साथ खोल सकते हैं crypto.subtle


2
यह कमाल का है। धन्यवाद। क्या तुलनीय एपीआई Node.js में उपलब्ध है?
कोन एंटाकॉस


17

फोर्ज का SHA-256 कार्यान्वयन तेज और विश्वसनीय है।

कई SHA-256 जावास्क्रिप्ट कार्यान्वयन पर परीक्षण चलाने के लिए, http://brillout.github.io/test-javascript-hash-implementations/ पर जाएं

मेरी मशीन के परिणामों से पता चलता है कि स्टैंफोर्ड जावास्क्रिप्ट क्रिप्टो लाइब्रेरी (sjcl) द्वारा स्वीकार किए गए उत्तर में उल्लिखित सबसे तेज़ कार्यान्वयन और भी काफी तेज़ है।

फोर्ज 256 KB बड़ा है, लेकिन SHA-256 संबंधित कोड निकालने से साइज 4.5 KB तक कम हो जाता है, https://github.com/brillout/forge-sha256 देखें


मैं इसे स्थापित करने में कामयाब रहा npm install node-forge, लेकिन अब, लाइब्रेरी का उपयोग करने के लिए स्ट्रिंग से एक हैश कैसे बनाएं foo?
उपयोगकर्ता

15

रुचि रखने वालों के लिए, यह SHA-256 हैश का उपयोग करने के लिए कोड है sjcl:

import sjcl from 'sjcl'

const myString = 'Hello'
const myBitArray = sjcl.hash.sha256.hash(myString)
const myHash = sjcl.codec.hex.fromBits(myBitArray)

4
यह उन लोगों के लिए स्वीकृत उत्तर में शामिल किया जाना चाहिए जो वहां समाधान का उपयोग करना चाहते हैं। (हेक, यहां तक ​​कि उनके अपने डॉक्स में भी इस तरह का स्निपेट नहीं है)
मैजिकलेंडेंड

यह सबसे अच्छा जवाब है। मैं क्रिप्टो समाधान की कोशिश कर रहा था, लेकिन यह मेरे लिए काम नहीं कर रहा था।
अगस्तो गोंजालेज

11

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

जावास्क्रिप्ट क्रिप्टोग्राफी वितरित करने के साथ "चिकन-अंडे की समस्या" क्या है?

यदि आप पासवर्ड देने के लिए नेटवर्क पर भरोसा नहीं करते हैं, या इससे भी बदतर है, तो सर्वर पर उपयोगकर्ता रहस्यों को न रखने के लिए भरोसा नहीं करते हैं, आप सुरक्षा कोड देने के लिए उन पर भरोसा नहीं कर सकते। क्रिप्टो शुरू करने से पहले पासवर्ड या रीडिंग डायरी सूँघने वाला एक ही हमलावर आपके द्वारा किए जाने के बाद क्रिप्टो कोड का अपहरण कर रहा है।

[...]

मैं जावास्क्रिप्ट क्रिप्टो कोड देने के लिए टीएलएस / एसएसएल का उपयोग क्यों नहीं कर सकता हूं?

आप ऐसा कर सकते हैं। यह लगता है की तुलना में कठिन है, लेकिन आप SSL का उपयोग करके जावास्क्रिप्ट क्रिप्टो को एक ब्राउज़र में सुरक्षित रूप से संचारित करते हैं। समस्या यह है कि एसएसएल के साथ एक सुरक्षित चैनल स्थापित करने के बाद, आपको जावास्क्रिप्ट क्रिप्टोग्राफी की आवश्यकता नहीं है; आपके पास "वास्तविक" क्रिप्टोग्राफी है।

जो इस की ओर जाता है:

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

अपने निष्पादन पर्यावरण को सत्यापित करने के लिए जावास्क्रिप्ट कोड के किसी भी टुकड़े के लिए कोई विश्वसनीय तरीका नहीं है। जावास्क्रिप्ट क्रिप्टो कोड नहीं पूछ सकता है, "क्या मैं वास्तव में एक यादृच्छिक संख्या जनरेटर के साथ काम कर रहा हूं, या एक हमलावर द्वारा प्रदान किए गए कुछ के साथ क्या कर सकता हूं?" और यह निश्चित रूप से जोर नहीं दे सकता है "किसी को भी इस क्रिप्टो रहस्य के साथ कुछ भी करने की अनुमति नहीं है सिवाय इसके कि मैं, लेखक, अनुमोदित"। ये दो गुण हैं जो अक्सर अन्य वातावरण में प्रदान किए जाते हैं जो क्रिप्टो का उपयोग करते हैं, और वे जावास्क्रिप्ट में असंभव हैं।

मूल रूप से समस्या यह है:

  • आपके ग्राहक आपके सर्वर पर भरोसा नहीं करते हैं, इसलिए वे अतिरिक्त सुरक्षा कोड जोड़ना चाहते हैं।
  • वह सुरक्षा कोड आपके सर्वर (वे जिस पर भरोसा नहीं करते) द्वारा दिया जाता है।

या वैकल्पिक रूप से,

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

नोट: इसके अलावा, SHA-256 इसके लिए उपयुक्त नहीं है, क्योंकि यह असंगत गैर-पुनरावृत्त पासवर्ड को बल देना बहुत आसान है । यदि आप ऐसा करने का निर्णय लेते हैं, तो bcrypt , scrypt या PBKDF2 के कार्यान्वयन की तलाश करें


1
यह सही नहीं है। क्लाइंट की ओर से हैशिंग द्वारा पासवर्ड सुरक्षा में सुधार किया जा सकता है। यह भी गलत है कि SHA-256 तब तक अनसुना किया जाता है जब तक सर्वर पर PBKDF2 जैसी किसी चीज का उपयोग नहीं किया जाता है। तीसरा, जबकि मैटासानो लेख में उपयोगी अंतर्दृष्टि शामिल है, पंच लाइन गलत है क्योंकि अब हमारे पास ब्राउज़र एप्लिकेशन हैं जो मूल रूप से चिकन-एंड-एग समस्या को बदलते हैं।
user239558

2
आप सही हैं कि PBKDF2 का उपयोग क्लाइंट पर किया जाना चाहिए। क्लाइंट साइड जावास्क्रिप्ट क्रिप्टो के खिलाफ क्रोध मानता है कि प्रारंभिक पृष्ठ और बाद के अनुरोधों में समान सुरक्षा गुण हैं। यह स्पष्ट रूप से ब्राउज़र ऐप्स के लिए सही नहीं है, जहां प्रारंभिक पृष्ठ अलग से इंस्टॉल किया गया है और स्थिर है। यह कैश-सदा शब्दार्थ वाले किसी भी पृष्ठ के लिए सही नहीं है। इन मामलों में, यह TOFU है जो क्लाइंट साइड प्रोग्राम इंस्टॉल करते समय बिल्कुल वैसा ही है। यह अधिक जटिल सेटअपों में भी सच हो सकता है जहां सर्वर पर स्थिर और गतिशील पृष्ठों की सेवा अलग हो जाती है।
user239558

3
उपयोगकर्ता पासवर्ड तक पहुँच के लिए सिस्टम एडमिनिस्ट्रेटर से बचना वैध है, इसलिए क्लाइंट साइड में हैशिंग डीबीए या अन्य आईटी पेशेवरों को उपयोगकर्ता पासवर्ड देखने के लिए रोकते हैं और अन्य सेवाओं / प्रणालियों तक पहुंचने के लिए इसका पुन: उपयोग करने का प्रयास करते हैं, क्योंकि बहुत सारे उपयोगकर्ता अपने पासवर्ड दोहराते हैं। ।
यमदा

1
@Xenland आप जो भी कर रहे हैं वह एक नया पासवर्ड बना रहा है जो "टोकन + पासवर्ड" है। सभी मूल समस्याएं अभी भी लागू होती हैं। उदाहरण के लिए, एक हमलावर उन्हें टोकन + पासवर्ड भेजने के लिए जावास्क्रिप्ट को कोड के साथ बदल सकता है।
ब्रेंडन लॉन्ग

2
@Xenland चिकन और अंडे की समस्या आपके द्वारा भेजे गए अनुरोधों के साथ कुछ भी नहीं करती है। समस्या यह है कि आपका क्लाइंट जावास्क्रिप्ट कोड का उपयोग कर रहा है जो सुरक्षा कार्य करने के लिए असुरक्षित कनेक्शन पर डाउनलोड किया गया है । एक वेब ब्राउज़र में जावास्क्रिप्ट को सुरक्षित रूप से भेजने का एकमात्र तरीका यह है कि आप इसे टीएलएस पर सेवा दें, और एक बार ऐसा करने के बाद, आपको कुछ और करने की आवश्यकता नहीं है क्योंकि आपका कनेक्शन पहले से ही सुरक्षित है। इससे कोई फर्क नहीं पड़ता कि आपका प्रोटोकॉल क्या है यदि आप जावास्क्रिप्ट कोड का उपयोग कर रहे हैं जो एक हमलावर को बदल सकता है।
ब्रेंडन लॉन्ग

10

मुझे यह कार्यान्वयन बहुत आसान लगा। इसके अलावा एक उदार बीएसडी शैली लाइसेंस है:

jsSHA: https://github.com/Caligatio/jsSHA

मुझे SHA-256 हैश के हेक्स-स्ट्रिंग प्रतिनिधित्व को प्राप्त करने के लिए एक त्वरित तरीके की आवश्यकता थी। इसमें केवल 3 लाइनें लगीं:

var sha256 = new jsSHA('SHA-256', 'TEXT');
sha256.update(some_string_variable_to_hash);
var hash = sha256.getHash("HEX");

1

स्टैनफोर्ड लिबर के अलावा टायलर का उल्लेख है। मुझे jsrsasign बहुत उपयोगी लगा (Github repo here: https://github.com/kjur/jsrsasign )। मुझे नहीं पता कि यह कितना भरोसेमंद है, लेकिन मैंने SHA256, Base64, RSA, x509 आदि के अपने API का उपयोग किया है और यह बहुत अच्छी तरह से काम करता है। वास्तव में, इसमें स्टैनफोर्ड लिब भी शामिल है।

यदि आप सभी SHA256 करना चाहते हैं, तो jsrsasign एक ओवरकिल हो सकता है। लेकिन अगर आपके पास संबंधित क्षेत्र में अन्य आवश्यकताएं हैं, तो मुझे लगता है कि यह एक अच्छा फिट है।


2
यह उपयोग करने के लिए सुरक्षित और तेजी से होता है developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API
विटाली Zdanevich

2
सहमत हूं, लेकिन निष्पक्ष होने के लिए, मैंने 2015 में इस सवाल का जवाब दिया, जबकि मोज़िला की वेब क्रिप्टो एपीआई विनिर्देश जनवरी 2017
फ़ारवे
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.