Linux में sha256sum से फाइल कैसे सत्यापित करें
Linux में sha256sum कमांड का उपयोग करके डाउनलोड की गई फाइलों की अखंडता जांचें। इस गाइड में hash की तुलना करना और फाइल में बदलाव होने पर विफलता को देखना सिखाया गया है।
checksum के साथ डाउनलोड को दो मिनट में सत्यापित करें
checksum के साथ डाउनलोड को सत्यापित करने के लिए, प्राप्त की गई फ़ाइल का hash निकालें और किसी टूल को उस hash की तुलना प्रकाशक द्वारा प्रकाशित hash से करने दें। sha256sum काम के दोनों हिस्सों को पूरा करता है: यह स्वयं एक digest प्रिंट करता है, और -c के साथ यह digest की सूची को पढ़कर बताता है कि कौन सी फ़ाइलें मेल खाती हैं। यह गाइड आपके द्वारा बनाई गई फ़ाइल पर पूरी प्रक्रिया को चलाती है, और फिर उस फ़ाइल को जानबूझकर खराब करती है ताकि आप केवल पढ़ने के बजाय विफलता को घटित होते हुए देख सकें।
पूरी प्रक्रिया के दौरान एक वाक्य याद रखें। एक checksum आपको बताता है कि आपके पास मौजूद bytes वही हैं जिनसे digest तैयार हुआ था, और यह आपको कुछ नहीं बताता कि उन्हें किसने बनाया। उस दूसरे प्रश्न के लिए एक signature और एक ऐसे key की आवश्यकता होती है जिस पर आप भरोसा करते हैं। इस गाइड का अंतिम भाग ठीक यही दिखाता है कि इन दोनों के बीच की सीमा कहाँ है।
अभ्यास के लिए एक फाइल बनाएँ
एक scratch directory में काम करें ताकि यहाँ की गई कोई भी क्रिया सिस्टम के बाकी हिस्सों को प्रभावित न करे। नीचे दिए गए सभी commands GNU coreutils से हैं, जो किसी भी Ubuntu या Debian सर्वर पर मौजूद base command set का हिस्सा हैं, इसलिए कुछ भी install करने की आवश्यकता नहीं है।
mkdir -p ~/checksum-demo
cd ~/checksum-demo
printf 'the payload of a totally ordinary download\n' > payload.txt
sha256sum payload.txtआपको एक पंक्ति प्राप्त होगी: 64 hexadecimal characters, दो spaces, और फिर फाइल का नाम। ये 64 characters फाइल का digest हैं। command को दोबारा चलाएं और आप देखेंगे कि पंक्ति बिल्कुल वैसी ही है, क्योंकि hashing deterministic होती है: समान input हमेशा समान output देता है। फाइल का एक character बदलें और इसे फिर से चलाएं, तो digest थोड़ा सा भी नहीं बदलेगा। यह पूरी तरह से अलग दिखेगा, क्योंकि input का एक bit बदलने से लगभग आधे output bits बदल जाते हैं। यही वह गुण है जो 64-character string को 4 GB image के लिए एक उपयोगी विकल्प बनाता है।
SHA256SUMS फ़ाइल को सेव करें, फिर उसे चेक करें
स्क्रीन पर दिख रहा डाइजेस्ट एक दिन बाद बेकार हो जाता है। इसे एक फ़ाइल में लिखें, उसी फॉर्मेट में जिसे sha256sum स्वयं लिखता है, ताकि टूल बाद में इसे वापस पढ़ सके।
sha256sum payload.txt > SHA256SUMS
cat SHA256SUMS
sha256sum -c SHA256SUMSsha256sum -c सूची की प्रत्येक पंक्ति को पढ़ता है, उस पंक्ति पर नामित फ़ाइल का हैश निकालता है, और दोनों डाइजेस्ट की तुलना करता है। एक सफल रन प्रत्येक फ़ाइल के लिए एक पंक्ति प्रिंट करता है:
payload.txt: OKएग्जिट स्टेटस (exit status) को भी चेक करें, क्योंकि कोई स्क्रिप्ट उसे पढ़ती है और टेक्स्ट को कभी नहीं पढ़ती। एक सफल रन के बाद echo $?, 0 प्रिंट करता है। SHA256SUMS नाम एक नियम के बजाय एक परंपरा है, लेकिन डिस्ट्रिब्यूशन और अधिकांश रिलीज़ पेज इसका उपयोग करते हैं, इसलिए आप भी इसका उपयोग करें ताकि अगला व्यक्ति फ़ाइल खोले बिना ही जान सके कि उसमें क्या है।
एक बाइट बदलें और चेक फेल होते हुए देखें
अब जानबूझकर फाइल को खराब करें। यह कमांड offset 5 पर एक सिंगल बाइट लिखता है और बाकी सब कुछ वैसा ही रहने देता है, इसलिए फाइल की लंबाई और नाम वही रहता है।
printf 'X' | dd of=payload.txt bs=1 seek=5 conv=notrunc status=none
cat payload.txt
sha256sum -c SHA256SUMSconv=notrunc वह फ्लैग है जो मायने रखता है: इसके बिना, dd फाइल को उस बिंदु पर काट (truncate) देता है जहाँ लिखना बंद होता है, और आप नुकसान के एक अधिक स्पष्ट प्रकार का परीक्षण कर रहे होते। चेक अब यह प्रिंट करता है:
payload.txt: FAILED
sha256sum: WARNING: 1 computed checksum did NOT matchecho $?, 1 प्रिंट करता है। FAILED का अर्थ है कि फाइल पढ़ी गई थी और उसका digest उस सूची में मौजूद digest से मेल नहीं खाया। मूल बाइट्स को वापस रखें और पुष्टि करें कि चेक वापस OK पर आ गया है:
printf 'the payload of a totally ordinary download\n' > payload.txt
sha256sum -c SHA256SUMSयही पूरी आदत है। फाइल में कहीं भी, एक बाइट का अंतर FAILED उत्पन्न करता है। कनेक्शन टूटने के कारण अधूरा डाउनलोड, कल का बिल्ड सर्व करने वाला मिरर, ट्रांजिट के दौरान फाइल को फिर से लिखने वाला प्रॉक्सी, या खराब ब्लॉक लौटाने वाली डिस्क: ये सभी उसी एक लाइन पर ले जाते हैं।
जब सूची में ऐसी फाइल का नाम हो जिसे आपने डाउनलोड नहीं किया है
किसी डिस्ट्रीब्यूशन की वास्तविक SHA256SUMS फाइल उन सभी इमेजेस की सूची रखती है जिन्हें प्रोजेक्ट रिलीज करता है, और आपने उनमें से केवल एक को डाउनलोड किया है। उस स्थिति को यहाँ दोहराएं।
printf 'a second file\n' > notes.txt
sha256sum payload.txt notes.txt > SHA256SUMS.all
rm notes.txt
sha256sum -c SHA256SUMS.allpayload.txt: OK
sha256sum: notes.txt: No such file or directory
notes.txt: FAILED open or read
sha256sum: WARNING: 1 listed file could not be readFAILED open or read, FAILED से एक अलग विफलता है, और दोनों को मिलाने से समय बर्बाद होता है। FAILED का अर्थ है कि बाइट्स गलत हैं। FAILED open or read का अर्थ है कि sha256sum को फाइल मिली ही नहीं, इसलिए किसी भी चीज की तुलना नहीं की गई। वास्तविक डाउनलोड पर इसका सामान्य कारण वर्किंग डायरेक्टरी होती है, क्योंकि सूची में नाम उस स्थान के सापेक्ष होते हैं जहाँ से आप कमांड चलाते हैं। उस डायरेक्टरी में जाएँ जिसमें फाइल मौजूद है और कमांड को फिर से चलाएँ। केवल उसी की जाँच करने के लिए जो आपके पास वास्तव में है, यह कमांड दें:
sha256sum --ignore-missing -c SHA256SUMS.allयह payload.txt: OK प्रिंट करता है और 0 के साथ एग्जिट होता है। यदि सूचीबद्ध नामों में से कोई भी मौजूद नहीं है, तो --ignore-missing शून्य फाइलों पर चुपचाप सफल नहीं होता है। यह रिपोर्ट करता है कि no file was verified और यह नॉन-जीरो एग्जिट कोड देता है, जो कि वांछित व्यवहार है, क्योंकि एक ऐसा पास जो किसी भी चीज की जाँच नहीं करता, वह ऐसी विफलता है जिसे आप कभी नहीं देख पाएंगे।
बिना देखे प्रकाशित डाइजेस्ट को पेस्ट करना
64 हेक्साडेसिमल वर्णों की तुलना आँखों से करना ही वह आदत है जहाँ सुरक्षा चूक जाती है। लोग केवल पहले चार और अंतिम चार वर्णों की जाँच करके उसे सही मान लेते हैं, और एक दृढ़ हमलावर ठीक इसी तरह की तुलना की उम्मीद करता है। इसके बजाय टूल को तुलना करने दें। प्रकाशक से कॉपी किए गए डाइजेस्ट को EXPECTED में सेट करें, इसके लिए EXPECTED= के बाद पेस्ट की गई वैल्यू का उपयोग करें, फिर वह सिंगल लाइन बनाएँ जिसकी -c अपेक्षा करता है:
printf '%s %s\n' "$EXPECTED" payload.txt > payload.sha256
cat payload.sha256
sha256sum -c payload.sha256डाइजेस्ट और फ़ाइल नाम के बीच दो स्पेस होते हैं, इसीलिए फॉर्मेट स्ट्रिंग में दो स्पेस रखे गए हैं। यही वह स्वरूप है जिसे sha256sum लिखता है और जिसे -c पार्स करता है। केवल डाइजेस्ट वाली फ़ाइल एक चेकसम लाइन नहीं होती है, इसलिए चेक पूरी फ़ाइल को no properly formatted checksum lines found के साथ अस्वीकार कर देता है, बजाय इसके कि वह अनुमान लगाए कि आप किस फ़ाइल की बात कर रहे हैं। कुछ प्रोजेक्ट इसके बजाय BSD टैग्ड स्टाइल प्रकाशित करते हैं, जिसमें SHA256 (payload.txt) = के बाद डाइजेस्ट होता है। GNU coreutils इस स्वरूप को sha256sum --tag payload.txt के साथ लिखता है और -c के साथ पढ़ता है, इसलिए दोनों में से किसी भी स्वरूप को सहेजना ठीक है।
जब कोई चेक अजीब व्यवहार करे, तो cat -A SHA256SUMS के साथ सूची को देखें, जो हर लाइन के अंत को $ से चिह्नित करता है और उन वर्णों को दिखाता है जिन्हें आप अन्यथा नहीं देख सकते। ^M$ पर समाप्त होने वाली लाइन में Windows एडिटर से आया एक कैरिज रिटर्न हो सकता है। GNU sha256sum उस ट्रेलिंग वर्ण को अनदेखा कर देता है और फिर भी OK प्रिंट करता है, इसलिए CRLF सूची आपके चेक को खराब नहीं कर रही है, हालाँकि coreutils के बाहर के टूल इसे लेकर कम उदार होते हैं। अपने पास रखी कॉपी को tr -d '\r' < SHA256SUMS > SHA256SUMS.clean के साथ सामान्य (normalize) करें।
Checksum क्या प्रमाणित करता है, और क्या नहीं?
Checksum केवल एक बात प्रमाणित करता है: आपके डिस्क पर मौजूद बाइट्स वही हैं जिनसे प्रकाशित digest तैयार हुआ था। यह आकस्मिक क्षति (accidental damage) को पूरी तरह कवर करता है। यह उस लापरवाह हमलावर को भी रोकता है जिसने डाउनलोड मिरर पर फाइल बदल दी, लेकिन उस पेज को नहीं बदल सका जहाँ digest प्रकाशित था।
यह लेखक के बारे में कुछ भी प्रमाणित नहीं करता है। एक digest बाइट्स के बारे में एक तथ्य है, न कि लोगों के बारे में। यदि एक ही पेज फाइल और digest दोनों प्रदान करता है, तो जो कोई भी एक को बदल सकता है वह दूसरे को भी बदल सकता है, और आपकी OK लाइन का मतलब केवल यह है कि मिरर खुद से सहमत है। इसलिए यहाँ वह नियम है जो checksums को उपयोगी बनाता है: digest को उस स्थान के अलावा कहीं और से लें जहाँ से आपने फाइल ली है। उदाहरण के लिए, प्रोजेक्ट का अपना डोमेन TLS (transport layer security) के माध्यम से, जबकि इमेज किसी मिरर या टोरेंट से आई हो। अब एक हमलावर को एक के बजाय दो स्थानों को नियंत्रित करना होगा। यह इस बारे में भी कुछ नहीं कहता कि वे सत्यापित बाइट्स चलने पर क्या करेंगे, जो कि किसी भी ऐसी चीज से पूछने योग्य एक अलग सवाल है जो आपकी ओर से निष्पादित होती है, जैसे कि एक install script से लेकर आपके agent की अनुमतियों के साथ चलने वाला dsh plugin तक।
Algorithm भी मायने रखता है। अगस्त 2026 तक SHA-256 (secure hash algorithm, 256-bit output) में कोई ज्ञात collision नहीं है, यही कारण है कि प्रकाशक इसका उपयोग करते हैं। MD5 (message digest 5) और SHA-1 अब सुरक्षित नहीं हैं: 2004 से ही एक ही MD5 digest वाली दो अलग-अलग फाइलें बनाना संभव है, और 2020 में एक chosen-prefix SHA-1 collision प्रकाशित किया गया था। एक MD5SUMS फाइल अभी भी अधूरे डाउनलोड (truncated download) को पकड़ लेती है, क्योंकि यादृच्छिक भ्रष्टाचार (random corruption) एक तैयार किया गया collision नहीं है। यह किसी ऐसे व्यक्ति को नहीं रोक सकता जो आपको धोखा देने की कोशिश कर रहा है। जब कोई प्रोजेक्ट दोनों प्रकाशित करता है, तो SHA-256 लाइन का उपयोग करें।
जहाँ हस्ताक्षर (signatures) काम संभालते हैं
एक signature उस कमी को पूरा करता है जो एक digest खुला छोड़ देता है। प्रकाशक (publisher) एक private key के साथ digest file पर हस्ताक्षर करता है, और आप इसे उनकी public key: gpg --verify SHA256SUMS.asc SHA256SUMS के साथ जांचते हैं। यदि यह सफल होता है, तो इसका अर्थ है कि digests की सूची उसी व्यक्ति से आई है जिसके पास वह key है। इसके बाद sha256sum -c SHA256SUMS आपकी डिस्क पर मौजूद फाइल को उस सूची से जोड़ देता है, और यह श्रृंखला key से लेकर फाइल के bytes तक पूरी हो जाती है।
कमजोर कड़ी अब key बन जाती है। जिस पेज से फाइल डाउनलोड की गई है, उसी से key को भी fetch करना हमलावर को दोनों चीजें उपलब्ध करा देता है। GnuPG इस बारे में स्पष्ट है, और पहली बार verification करने पर यह Good signature के साथ WARNING: This key is not certified with a trusted signature! प्रिंट करता है। Good signature का अर्थ है कि गणितीय रूप से सब सही है। इसका यह अर्थ नहीं है कि key उसी प्रोजेक्ट की है जिसे आप सोच रहे हैं। fingerprint को किसी दूसरे स्रोत से प्राप्त करें, जैसे कि किसी अलग domain पर मौजूद प्रोजेक्ट का documentation या कोई distribution package जिसमें वह key पहले से शामिल हो, और अंतिम आठ characters के बजाय पूरे fingerprint की तुलना करें। इसके लिए वही सावधानी बरतें जो एक SSH private key के लिए जरूरी है, क्योंकि कारण वही है: key ही विश्वास का आधार है, और इसके बाद की हर चीज इसी से प्रमाणित होती है।
Reproducible builds इस विचार को एक कदम और आगे ले जाते हैं। एक प्रकाशित digest आपको उस binary से बांध देता है जिसे किसी एक मशीन ने बनाया है। जब किसी प्रोजेक्ट का build reproducible होता है, तो कोई भी व्यक्ति उसी source code को compile करके byte-के-स्तर पर समान output प्राप्त कर सकता है। इससे स्वतंत्र builders प्रकाशित digest की पुष्टि कर सकते हैं, बजाय इसके कि आप केवल एक सर्वर के दावे पर भरोसा करें। यह हर साल अधिक महत्वपूर्ण होता जा रहा है, क्योंकि अधिक code automated pipelines और machine-written patches के माध्यम से आ रहा है। आप build में क्या स्वीकार करते हैं, यह एक policy का प्रश्न है, और AI-assisted code के लिए open source policies उसी supply chain पर दूसरे छोर से काम करती हैं।
आपका पैकेज मैनेजर यह काम पहले से ही आपके लिए करता है
Debian और Ubuntu पर, apt हर इंस्टॉलेशन के दौरान बिना कहे यह चेन चलाता है। पैकेज इंडेक्स में प्रत्येक .deb फ़ाइल के लिए एक SHA-256 डाइजेस्ट होता है। Release फ़ाइल में उन इंडेक्स फ़ाइलों के डाइजेस्ट होते हैं, और InRelease में Release पर एक सिग्नेचर होता है, जिसे /usr/share/keyrings और /etc/apt/trusted.gpg.d में मौजूद कीज़ (keys) के साथ चेक किया जाता है। जब यह चेन टूटती है, तो apt इसकी सूचना देता है: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY तब आता है जब किसी थर्ड-पार्टी रिपॉजिटरी की की (key) गायब होती है, या Hash Sum mismatch तब आता है जब आपके द्वारा प्राप्त इंडेक्स हस्ताक्षरित Release से मेल नहीं खाता है। इसका मतलब आमतौर पर यह होता है कि किसी कैशिंग प्रॉक्सी ने पुरानी फ़ाइल दी है या आप मिरर के सिंक होने के दौरान उसे एक्सेस कर रहे थे।
जब किसी प्रोजेक्ट का होम पेज आपको curl से सीधे शेल में स्क्रिप्ट पाइप करने के लिए कहता है, तो यह वह मानक है जिसके आधार पर आपको तुलना करनी चाहिए। कोई भी चीज़ बाइट्स को सत्यापित नहीं करती है और आप उन्हें कभी देख नहीं पाते हैं। सर्वर स्क्रिप्ट को कुछ और और ब्राउज़र को कुछ और भी भेज सकता है, और आपके पास बाद में निरीक्षण करने के लिए कोई कॉपी नहीं होती है। curl -fsSL <url> -o install.sh के साथ फ़ाइल डाउनलोड करें, उसका हैश निकालें, उसे less के साथ पढ़ें, और उसके बाद ही उसे चलाएं। इस आदत में लगभग बीस सेकंड का समय लगता है, और यही वह आदत है जिसे एक बिल्कुल नए VPS के पहले दस मिनट में शुरू करना उचित है, इससे पहले कि बॉक्स पर कुछ और इंस्टॉल किया जाए।
मैन्युअल रूप से इंस्टॉल की गई फाइलों के डाइजेस्ट (digests) की सूची रखें
apt द्वारा इंस्टॉल किए गए पैकेज ट्रैक किए जाते हैं। /usr/local/bin में कॉपी की गई कोई बाइनरी ट्रैक नहीं होती है और सिस्टम पर कोई भी इसकी निगरानी नहीं कर रहा होता है। डाइजेस्ट की एक सूची इसे ऐसी चीज में बदल देती है जिसे आप मांग पर चेक कर सकते हैं:
printf 'a second file\n' > notes.txt
sha256sum *.txt > inventory.sha256
sha256sum -c --quiet inventory.sha256--quiet तब कुछ भी प्रिंट नहीं करता है जब हर फाइल मेल खाती है, और केवल उन लाइनों को प्रिंट करता है जो विफल हो जाती हैं, इसलिए शांति का अर्थ है पास होना और echo $? इसे 0 के साथ पुष्टि करता है। यह वह प्रारूप है जिसे एक निर्धारित जॉब (scheduled job) में रखा जाना चाहिए। --status और आगे जाता है और कुछ भी प्रिंट नहीं करता है, जिससे आपको केवल एग्जिट स्टेटस मिलता है। उसी पैटर्न को sha256sum /usr/local/bin/* > ~/local-bin.sha256 के साथ वास्तविक फाइलों पर लागू करें और आपके पास एक बेसलाइन तैयार हो जाएगी। पाथ (paths) को सूची में बिल्कुल वैसे ही स्टोर किया जाता है जैसे आपने उन्हें टाइप किया था, इसलिए एब्सोल्यूट पाथ (absolute paths) किसी भी डायरेक्टरी से चेक को काम करने में सक्षम बनाते हैं।
यह स्पष्ट रखें कि वह बेसलाइन कितनी मूल्यवान है। यह एक बदली हुई फाइल का पता लगाती है। यह उस हमलावर का पता नहीं लगाती है जिसके पास पहले से ही root एक्सेस है, क्योंकि वह हमलावर inventory.sha256 को उतनी ही आसानी से फिर से लिख सकता है जितनी आसानी से उसने बाइनरी को लिखा था। यदि आप चाहते हैं कि इस सूची का कोई अर्थ हो, तो इसे मशीन से बाहर रखें, जो आप वास्तव में VPS के कितने हिस्से पर भरोसा कर रहे हैं के व्यापक प्रश्न का हिस्सा है और यह भी कि डिस्क तक और कौन पहुँच सकता है।
FAQ
क्या matching checksum का मतलब है कि download सुरक्षित है?
नहीं। इसका मतलब केवल यह है कि आपके पास मौजूद bytes उस digest से मेल खाते हैं जिससे आपने उनकी तुलना की है। यदि हमलावर उस पेज को नियंत्रित करता है जहाँ digest प्रकाशित किया गया है, तो वे अपनी फाइल का digest प्रकाशित कर देंगे और आपका check OK दिखाएगा। एक match केवल consistency का दावा है। सुरक्षा का दावा करने के लिए एक ऐसी signature की आवश्यकता होती है जिसे किसी अन्य स्रोत से प्राप्त key के माध्यम से verify किया गया हो, और केवल तभी digest को वह विश्वास प्राप्त होता है।
sha256sum -c, FAILED open or read क्यों print करता है?
क्योंकि इसने फाइल को पढ़ा ही नहीं है। इसके ठीक ऊपर एक अलग लाइन में No such file or directory लिखा होता है, जिसमें उस फाइल का नाम होता है जिसे यह ढूँढ रहा था। SHA256SUMS फाइल के अंदर के नाम उस directory के सापेक्ष (relative) होते हैं जिसमें आप command चलाते हैं, इसलिए उस directory में जाएँ जहाँ download मौजूद है और इसे फिर से चलाएँ। यदि सूची में ऐसी फाइलें भी हैं जिन्हें आपने download नहीं किया है, तो --ignore-missing जोड़ें। बिना open or read के एक साधारण FAILED इसके विपरीत स्थिति है: फाइल पढ़ी गई थी, और उसका digest मेल नहीं खाया।
क्या download verify करने के लिए MD5 पर्याप्त है?
आकस्मिक क्षति (accidental damage) के लिए, हाँ। एक अधूरा transfer या खराब disk block संयोग से मेल खाता MD5 digest उत्पन्न नहीं करेगा। एक हमलावर के खिलाफ, नहीं। 2004 से ही समान MD5 digest वाली दो अलग-अलग फाइलें बनाना संभव है, और 2020 में SHA-1 एक chosen-prefix collision के कारण विफल हो गया था। जब कोई project दोनों प्रकाशित करता है, तो SHA-256 लाइन का उपयोग करें, और केवल MD5 वाले project को एक पुरानी release प्रक्रिया का संकेत मानें।
sha256sum -c और gpg --verify के बीच क्या अंतर है?
sha256sum -c यह सिद्ध करता है कि फाइल एक digest से मेल खाती है। gpg --verify यह सिद्ध करता है कि digest फाइल को एक विशेष private key के धारक द्वारा sign किया गया था। वे अलग-अलग सवालों के जवाब देते हैं, इसलिए जब कोई project दोनों प्रदान करे तो दोनों चलाएँ। Signature digest सूची को विश्वसनीय बनाती है, और फिर digest सूची download की गई फाइल को विश्वसनीय बनाती है।
मैं वेब पेज पर छपे digest के साथ एक फाइल को कैसे check करूँ?
अक्षरों की तुलना आँखों से न करें। digest और फाइल के नाम को एक ही लाइन में, दो spaces से अलग करके save करें, फिर उस फाइल पर sha256sum -c चलाएँ और जो OK या FAILED यह print करे उसे पढ़ें। printf '%s %s\n' के साथ लाइन बनाने से वे formatting की गलतियाँ नहीं होतीं जिनके कारण sha256sum फाइल को no properly formatted checksum lines found के साथ reject कर देता है।