Linux में sha256sum से फाइल वेरिफाई कैसे करें
Linux में sha256sum कमांड का उपयोग करके फाइलों की अखंडता की जांच करना सीखें। हम SHA256SUMS फाइल से मिलान करना और एक बाइट बदलकर चेकसम फेल होने का लाइव डेमो भी दिखाएंगे।
दो मिनट में चेकसम के साथ डाउनलोड को सत्यापित करें
डाउनलोड को चेकसम के साथ सत्यापित करने के लिए, प्राप्त फ़ाइल का हैश निकालें और किसी टूल को उस हैश की तुलना प्रकाशक द्वारा प्रकाशित हैश से करने दें। sha256sum काम के दोनों हिस्सों को पूरा करता है: यह अकेले एक डाइजेस्ट प्रिंट करता है, और -c के साथ यह डाइजेस्ट की एक सूची पढ़ता है और बताता है कि कौन सी फ़ाइलें मेल खाती हैं। यह गाइड आपके द्वारा बनाई गई फ़ाइल पर पूरा लूप चलाती है, और फिर उस फ़ाइल को जानबूझकर खराब करती है ताकि आप विफलता के बारे में पढ़ने के बजाय उसे होते हुए देख सकें।
पूरी प्रक्रिया के दौरान एक वाक्य ध्यान में रखें। चेकसम आपको बताता है कि आपके पास मौजूद बाइट्स वही हैं जिनसे डाइजेस्ट तैयार हुआ था, और यह आपको कुछ नहीं बताता कि उन्हें किसने बनाया है। उस दूसरे प्रश्न के लिए एक हस्ताक्षर और एक ऐसी की (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एग्जिट स्टेटस की भी जाँच करें, क्योंकि एक स्क्रिप्ट उसे पढ़ती है और टेक्स्ट को कभी नहीं पढ़ती। एक सफल रन के बाद echo $?, 0 प्रिंट करता है। SHA256SUMS नाम एक नियम के बजाय एक परंपरा है, लेकिन डिस्ट्रिब्यूशन और अधिकांश रिलीज़ पेज इसका उपयोग करते हैं, इसलिए आप भी इसका उपयोग करें ताकि अगला व्यक्ति इसे खोले बिना जान सके कि फ़ाइल में क्या है।
एक बाइट बदलें और चेक फेल होते हुए देखें
अब जानबूझकर फाइल को खराब करें। यह कमांड ऑफसेट 5 पर एक सिंगल बाइट लिखता है और बाकी सब कुछ वैसा ही रहने देता है, इसलिए फाइल की लंबाई और उसका नाम वही रहता है।
printf 'X' | dd of=payload.txt bs=1 seek=5 conv=notrunc status=none
cat payload.txt
sha256sum -c SHA256SUMSconv=notrunc वह फ्लैग है जो मायने रखता है: इसके बिना, dd फाइल को उस बिंदु पर ट्रंकेट (काट) देता है जहाँ लिखना बंद होता है, और आप नुकसान के एक अधिक स्पष्ट प्रकार का परीक्षण कर रहे होते। चेक अब यह प्रिंट करता है:
payload.txt: FAILED
sha256sum: WARNING: 1 computed checksum did NOT matchecho $?, 1 प्रिंट करता है। FAILED का अर्थ है कि फाइल पढ़ी गई थी और उसका डाइजेस्ट लिस्ट में मौजूद डाइजेस्ट से मेल नहीं खाया। मूल बाइट्स को वापस रखें और पुष्टि करें कि चेक वापस 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 एडिटर से आया एक carriage return हो सकता है। GNU sha256sum उस अंतिम वर्ण को अनदेखा कर देता है और फिर भी OK प्रिंट करता है, इसलिए CRLF सूची आपके चेक को खराब नहीं कर रही है, हालाँकि coreutils के बाहर के टूल इसके प्रति कम उदार होते हैं। अपने पास रखी कॉपी को tr -d '\r' < SHA256SUMS > SHA256SUMS.clean के साथ सामान्य (normalise) करें।
Checksum क्या प्रमाणित करता है, और क्या नहीं?
Checksum केवल एक बात प्रमाणित करता है: आपकी डिस्क पर मौजूद बाइट्स वही हैं जिनसे प्रकाशित digest तैयार हुआ था। यह आकस्मिक क्षति (accidental damage) को पूरी तरह कवर करता है। यह उस लापरवाह हमलावर को भी पकड़ लेता है जिसने डाउनलोड मिरर पर फाइल तो बदल दी, लेकिन उस पेज को नहीं बदल पाया जहाँ digest प्रकाशित था।
यह लेखक के बारे में कुछ भी प्रमाणित नहीं करता है। Digest बाइट्स के बारे में एक तथ्य है, न कि लोगों के बारे में। यदि एक ही पेज फाइल और digest दोनों प्रदान करता है, तो जो कोई भी एक को बदल सकता है वह दूसरे को भी बदल सकता है, और आपकी OK लाइन का मतलब केवल इतना है कि मिरर खुद से सहमत है। इसलिए यहाँ वह नियम है जो checksums को उपयोगी बनाता है: digest को उस स्थान से अलग कहीं और से लें जहाँ से आपने फाइल ली है। उदाहरण के लिए, प्रोजेक्ट का अपना डोमेन TLS (transport layer security) के माध्यम से, जबकि इमेज किसी मिरर या torrent से आई हो। अब हमलावर को एक के बजाय दो स्थानों को नियंत्रित करना होगा।
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) को पकड़ लेती है, क्योंकि रैंडम करप्शन एक तैयार किया गया collision नहीं होता है। यह किसी ऐसे व्यक्ति को नहीं रोक सकता जो आपको धोखा देने की कोशिश कर रहा है। जब कोई प्रोजेक्ट दोनों प्रकाशित करता है, तो SHA-256 लाइन का ही उपयोग करें।
जहाँ हस्ताक्षर (signatures) कार्यभार संभालते हैं
एक हस्ताक्षर उस कमी को पूरा करता है जो एक digest छोड़ देता है। प्रकाशक एक private key के साथ digest फ़ाइल पर हस्ताक्षर करता है, और आप इसे उनकी public key के साथ जाँचते हैं: gpg --verify SHA256SUMS.asc SHA256SUMS। यदि यह सफल होता है, तो इसका अर्थ है कि digest की सूची उसी व्यक्ति से आई है जिसके पास वह key है। इसके बाद sha256sum -c SHA256SUMS आपकी डिस्क पर मौजूद फ़ाइल को उस सूची से जोड़ता है, और यह श्रृंखला key से लेकर फ़ाइल के bytes तक पूरी तरह सुरक्षित रहती है।
कमजोर कड़ी अब key बन जाती है। जिस पेज से आपने फ़ाइल डाउनलोड की है, उसी से key प्राप्त करना हमलावर को दोनों चीजें उपलब्ध करा देता है। 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 और मशीन द्वारा लिखे गए 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 के पहले दस मिनट में शुरू करना उचित है, इससे पहले कि बॉक्स पर कुछ और इंस्टॉल किया जाए।
मैन्युअल रूप से इंस्टॉल की गई फाइलों के डाइजेस्ट की सूची रखें
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) सूची में बिल्कुल वैसे ही संग्रहीत होते हैं जैसे आपने उन्हें टाइप किया था, इसलिए एब्सोल्यूट पाथ किसी भी डायरेक्टरी से चेक को काम करने योग्य बनाते हैं।
स्पष्ट रहें कि वह बेसलाइन कितनी मूल्यवान है। यह एक बदली हुई फाइल का पता लगाती है। यह उस हमलावर का पता नहीं लगाती है जिसके पास पहले से ही 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 के सापेक्ष होते हैं जिसमें आप 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 की गई फाइल को विश्वसनीय बनाती है।
मैं web page पर छपे digest के विरुद्ध एक फाइल को कैसे check करूँ?
अक्षरों की तुलना आँखों से न करें। digest और फाइल के नाम को एक ही लाइन में दो spaces से अलग करके save करें, फिर उस फाइल पर sha256sum -c चलाएँ और जो OK या FAILED यह print करे उसे पढ़ें। printf '%s %s\n' के साथ लाइन बनाने से वे formatting की गलतियाँ नहीं होतीं जिनके कारण sha256sum फाइल को no properly formatted checksum lines found के साथ reject कर देता है।