MySQL में SHA1 हैश मान संग्रहीत करना


160

मेरे पास एक साधारण प्रश्न है जो तब हुआ जब मैं एक MySQL डेटाबेस में SHA1 हैश के परिणाम को संग्रहीत करना चाहता था:

कब तक VARCHAR फ़ील्ड होना चाहिए जिसमें मैं हैश का परिणाम संग्रहीत करता हूं?


9
यदि आप अभी भी googled sha1 पर क्लिक करते हैं, तो आप भाग्यशाली महसूस कर रहे हैं और आपको विकिपीडिया पर होना चाहिए जहाँ आप पा सकते हैं कि यह हमेशा 160 बिट्स का है।
टिम मैथ्यूज

जवाबों:


315

मैं VARCHARचर लंबाई डेटा के लिए उपयोग करूंगा , लेकिन निश्चित लंबाई डेटा के साथ नहीं। क्योंकि SHA-1 मान हमेशा 160 बिट लंबा होता है, इसलिए VARCHARयह निर्धारित लंबाई वाले क्षेत्र की लंबाई के लिए अतिरिक्त बाइट बर्बाद करेगा ।

और मैं भी मूल्य नहीं SHA1लौटा रहा हूँ। क्योंकि यह प्रति वर्ण केवल 4 बिट का उपयोग करता है और इस प्रकार 160/4 = 40 वर्णों की आवश्यकता होगी। लेकिन यदि आप प्रति वर्ण 8 बिट का उपयोग करते हैं, तो आपको केवल 160/8 = 20 वर्ण लंबे क्षेत्र की आवश्यकता होगी।

तो मैं आपको उपयोग करने की सलाह देता हूं BINARY(20)और मान को बाइनरी में बदलने के लिए UNHEXफ़ंक्शन करता हूं SHA1

मैंने BINARY(20)और उसके लिए भंडारण आवश्यकताओं की तुलना की CHAR(40)

CREATE TABLE `binary` (
    `id` int unsigned auto_increment primary key,
    `password` binary(20) not null
);
CREATE TABLE `char` (
    `id` int unsigned auto_increment primary key,
    `password` char(40) not null
);

मिलियन रिकॉर्ड्स binary(20)में 44.56M लगते हैं, जबकि char(40)64.57M लगते हैं। InnoDBयन्त्र।


2
PostgreSQL में, यह एक बाइट फ़ील्ड का उपयोग करने के लिए अनुवाद करेगा, है ना?
मावेक्सेल

समाधान बहुत अच्छा है, लेकिन हेक्सेड शा 1 के साथ चार (40) का उपयोग करने का एक और बिंदु है - यह बहुत अधिक व्यापक रूप से उपयोग किया जाता है, और एक आवेदन कोड में कम रूपांतरण के मुद्दे होंगे।
आर्थर कुशमैन

2
Phpmyadmin उपयोगकर्ताओं के लिए ध्यान दें। जब हैश को बाइनरी के रूप में संग्रहीत किया जाता है, तो phpmyadmin इसे हेक्स स्ट्रिंग के रूप में प्रदर्शित करेगा, लेकिन pma प्रदान की गई "खोज टैब" में इसका उपयोग करने में असमर्थ होगा। यदि आप UNHEX()मैन्युअल रूप से वर्ग में जोड़ते हैं तो ही काम करेगा ।
टिमो हुओवेनन

2
@Gumbo आप एक बाइट में बाइट्स की एक चर संख्या स्टोर कर सकते हैं। आप बाइट प्रकार की भंडारण आवश्यकताओं का उल्लेख कर रहे हैं। जो "1 या 4 बाइट्स और वास्तविक बाइनरी स्ट्रिंग" है। क्या "1 या 4" संदर्भित करता है संग्रहीत डेटा की लंबाई हो सकती है, क्योंकि आप स्ट्रिंग को समाप्त करने के लिए एक शून्य बाइट का उपयोग नहीं कर सकते हैं जैसा कि आप varchar के साथ करते हैं। इसका मतलब है, लेकिन मैनुअल में यह नहीं बताया गया है कि आप एक बाइट में 2 ^ (8 * 4) या 4+ गीगाबाइट तक स्टोर कर सकते हैं। postgresql.org/docs/9.0/static/datatype-binary.html हैश को पोस्टग्रैज डेटाबेस में संग्रहीत करना शायद एक बिट या बाइट कॉलम के रूप में सबसे छोटा होगा ।
विक्टर

2
dev.mysql.com/doc/refman/5.5/en/… क्रिप्ट फ़ंक्शंस के परिणामों को संग्रहीत करते समय प्रदर्शन और भंडारण के बारे में जानकारी प्रदान करता है
घड़ीसाज़


11

इस ब्लॉग से लिया गया संदर्भ:

नीचे हैशिंग एल्गोरिथ्म की एक सूची दी गई है जिसमें इसकी आवश्यकता बिट आकार के साथ है:

  • MD5 = 128-बिट हैश मान।
  • SHA1 = 160-बिट हैश मान।
  • SHA224 = 224-बिट हैश मान।
  • SHA256 = 256-बिट हैश मान।
  • SHA384 = 384-बिट हैश मान।
  • SHA512 = 512-बिट हैश मान।

CHAR (n) की आवश्यकता के साथ एक नमूना तालिका बनाई गई:

CREATE TABLE tbl_PasswordDataType
(
    ID INTEGER
    ,MD5_128_bit CHAR(32)
    ,SHA_160_bit CHAR(40)
    ,SHA_224_bit CHAR(56)
    ,SHA_256_bit CHAR(64)
    ,SHA_384_bit CHAR(96)
    ,SHA_512_bit CHAR(128)
); 
INSERT INTO tbl_PasswordDataType
VALUES 
(
    1
    ,MD5('SamplePass_WithAddedSalt')
    ,SHA1('SamplePass_WithAddedSalt')
    ,SHA2('SamplePass_WithAddedSalt',224)
    ,SHA2('SamplePass_WithAddedSalt',256)
    ,SHA2('SamplePass_WithAddedSalt',384)
    ,SHA2('SamplePass_WithAddedSalt',512)
);

10
कृपया, कृपया , कृपया वास्तव में इस तरह से पासवर्ड स्टोर न करें।
बेरी एम।

हे बेरी, क्या आप अपने WHY की व्याख्या कर सकते हैं? विवरण में
Anvesh

4
पासवर्डों के साधारण हैश को संग्रहीत करने से पासवर्ड को "निकाले जाने" के लिए बहुत आसान हो जाता है यदि आपके डेटाबेस से समझौता किया जाता है यदि आप एक नमकीन (उम्मीद से फैला हुआ) पासवर्ड हैश का उपयोग करते हैं। पढ़ने का सुझाव: paragonie.com/blog/2016/02/how-safely-store-password-in-2016
मैट

2
@BerryM। एक साल बाद इसे पढ़ना, और एक सेकंड के लिए नहीं सोचा था कि कोई भी पासवर्ड के बारे में बात कर रहा है या अगर लोग अभी भी साधारण हैश का उपयोग डेटा को संग्रहीत करने के लिए करते हैं। लेकिन वे करते हैं: डी
रोहित हजरा

6

Sha1 का आउटपुट साइज़ 160 बिट्स है। जो 160/8 == 20 वर्ण (यदि आप 8-बिट चार्ट का उपयोग करते हैं) या 160/16 = 10 (यदि आप 16-बिट चार्ट का उपयोग करते हैं)।


8-बिट बाइनरी वर्णों को मानते हुए। 40 वर्ण यदि हेक्स के रूप में संग्रहीत हैं।
टाइजॉइड 17

3

तो लंबाई 10 16-बिट वर्ण और 40 हेक्स अंकों के बीच है।

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


2

आप अभी भी उन मामलों में वर्च का उपयोग करना चाहते हैं, जहाँ आप हमेशा उपयोगकर्ता के लिए हैश नहीं जमा करते हैं (अर्थात खातों को प्रमाणित करना / लॉगिन यूआरएल भूल जाना)। एक बार जब कोई उपयोगकर्ता अपनी लॉगिन जानकारी को प्रमाणित / बदल देता है, तो उन्हें हैश का उपयोग करने में सक्षम नहीं होना चाहिए और इसका कोई कारण नहीं होना चाहिए। आप अस्थायी हैश -> उपयोगकर्ता संघों को संग्रहीत करने के लिए एक अलग तालिका बना सकते हैं जिसे हटाया जा सकता है लेकिन मुझे नहीं लगता कि अधिकांश लोग ऐसा करने के लिए परेशान होते हैं।


2

यदि आपको sha1 कॉलम पर एक इंडेक्स की आवश्यकता है, तो मैं प्रदर्शन कारणों से CHAR (40) का सुझाव देता हूं। मेरे मामले में sha1 कॉलम एक ईमेल पुष्टिकरण टोकन है, इसलिए लैंडिंग पृष्ठ पर क्वेरी केवल टोकन के साथ प्रवेश करती है। इस मामले में, INDEX के साथ CHAR (40), मेरी राय में, सबसे अच्छा विकल्प है :)

यदि आप इस विधि को अपनाना चाहते हैं, तो $ raw_output = false को याद रखें।


1
आप BINARY (20) को इंडेक्स क्यों नहीं करेंगे? क्या यह उतना तेज और आधा आकार में बड़ा नहीं होगा?
निकल्डन

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

1
मुझे लगता है कि अगर आप एक पंक्ति को लाने के लिए unhex (हैश) = हैश से चयन के अलावा कुछ भी कर रहे हैं, तो आप सही हैं। लेकिन इंडेक्स को बफर्ड रखने से इस तरह से दोगुनी मेमोरी लगेगी।
निकडन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.