Go
क्रिप्टोग्राफी
खोज…
परिचय
गो के साथ डेटा को एन्क्रिप्ट और डिक्रिप्ट करने का तरीका जानें। ध्यान रखें कि यह क्रिप्टोग्राफी के बारे में एक कोर्स नहीं है, बल्कि इसे गो के साथ कैसे प्राप्त किया जाए।
एन्क्रिप्शन और डिक्रिप्शन
प्रस्तावना
गो के साथ डेटा को एन्क्रिप्ट और डिक्रिप्ट करने के तरीके के बारे में यह एक विस्तृत उदाहरण है। उपयोग कोड छोटा है, उदाहरण के लिए त्रुटि से निपटने का उल्लेख नहीं किया गया है। त्रुटि हैंडलिंग और उपयोगकर्ता इंटरफ़ेस के साथ पूर्ण कार्य परियोजना यहां जीथब पर पाई जा सकती है ।
एन्क्रिप्शन
परिचय और डेटा
यह उदाहरण एक पूर्ण कार्य एन्क्रिप्शन और गो में डिक्रिप्शन का वर्णन करता है। ऐसा करने के लिए, हमें एक डेटा की आवश्यकता है। इस उदाहरण में, हम अपनी स्वयं की डेटा संरचना का उपयोग secret
:
type secret struct {
DisplayName string
Notes string
Username string
EMail string
CopyMethod string
Password string
CustomField01Name string
CustomField01Data string
CustomField02Name string
CustomField02Data string
CustomField03Name string
CustomField03Data string
CustomField04Name string
CustomField04Data string
CustomField05Name string
CustomField05Data string
CustomField06Name string
CustomField06Data string
}
अगला, हम इस तरह के secret
को एन्क्रिप्ट करना चाहते हैं। पूरा काम करने वाला उदाहरण यहां पाया जा सकता है (गीथूब से लिंक) । अब, चरण-दर-चरण प्रक्रिया:
चरण 1
सबसे पहले, हमें गुप्त को संरक्षित करने के लिए एक प्रकार के मास्टर पासवर्ड की आवश्यकता है: masterPassword := "PASS"
चरण 2
स्ट्रिंग्स के बजाय बाइट्स के साथ काम करने वाले सभी क्रिप्टो तरीके। इस प्रकार, हम अपने रहस्य से डेटा के साथ एक बाइट सरणी का निर्माण करते हैं।
secretBytesDecrypted := []byte(fmt.Sprintf("%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n",
artifact.DisplayName,
strings.Replace(artifact.Notes, "\n", string(65000), -1),
artifact.Username,
artifact.EMail,
artifact.CopyMethod,
artifact.Password,
artifact.CustomField01Name,
artifact.CustomField01Data,
artifact.CustomField02Name,
artifact.CustomField02Data,
artifact.CustomField03Name,
artifact.CustomField03Data,
artifact.CustomField04Name,
artifact.CustomField04Data,
artifact.CustomField05Name,
artifact.CustomField05Data,
artifact.CustomField06Name,
artifact.CustomField06Data,
))
चरण 3
हम इंद्रधनुष तालिका हमलों को रोकने के लिए कुछ नमक बनाते हैं, सीएफ। विकिपीडिया : saltBytes := uuid.NewV4().Bytes()
। यहां, हम एक UUID v4 का उपयोग करते हैं जो कि अनुमानित नहीं है।
चरण 4
अब, हम RFC 2898 के बारे में मास्टर पासवर्ड और बेतरतीब नमक से एक कुंजी और एक वेक्टर प्राप्त करने में सक्षम हैं:
keyLength := 256
rfc2898Iterations := 6
keyVectorData := pbkdf2.Key(masterPassword, saltBytes, rfc2898Iterations, (keyLength/8)+aes.BlockSize, sha1.New)
keyBytes := keyVectorData[:keyLength/8]
vectorBytes := keyVectorData[keyLength/8:]
चरण 5
वांछित सीबीसी मोड पूरे ब्लॉक के साथ काम करता है। इस प्रकार, हमें यह देखना होगा कि क्या हमारा डेटा एक पूर्ण ब्लॉक से जुड़ा हुआ है। यदि नहीं, तो हमें इसे पैड करना होगा:
if len(secretBytesDecrypted)%aes.BlockSize != 0 {
numberNecessaryBlocks := int(math.Ceil(float64(len(secretBytesDecrypted)) / float64(aes.BlockSize)))
enhanced := make([]byte, numberNecessaryBlocks*aes.BlockSize)
copy(enhanced, secretBytesDecrypted)
secretBytesDecrypted = enhanced
}
चरण 6
अब हम AES सिफर बनाते हैं: aesBlockEncrypter, aesErr := aes.NewCipher(keyBytes)
चरण 7
हम एन्क्रिप्टेड डेटा के लिए आवश्यक मेमोरी को आरक्षित करते हैं: encryptedData := make([]byte, len(secretBytesDecrypted))
। एईएस-सीबीसी के मामले में, एन्क्रिप्ट किए गए डेटा की लंबाई अनएन्क्रिप्टेड डेटा के समान थी।
चरण 8
अब, हमें एनक्रिप्ट बनाना चाहिए और डेटा एन्क्रिप्ट करना चाहिए:
aesEncrypter := cipher.NewCBCEncrypter(aesBlockEncrypter, vectorBytes)
aesEncrypter.CryptBlocks(encryptedData, secretBytesDecrypted)
अब, एन्क्रिप्टेड डाटा के अंदर है encryptedData
चर।
चरण 9
एन्क्रिप्टेड डेटा संग्रहीत किया जाना चाहिए। लेकिन न केवल डेटा: नमक के बिना, एन्क्रिप्ट किए गए डेटा को डिक्रिप्ट नहीं किया जा सकता है। इस प्रकार, हमें इसे प्रबंधित करने के लिए किसी प्रकार के फ़ाइल प्रारूप का उपयोग करना चाहिए। यहाँ, हम एन्क्रिप्टेड डेटा को base64, cf. विकिपीडिया :
encodedBytes := make([]byte, base64.StdEncoding.EncodedLen(len(encryptedData)))
base64.StdEncoding.Encode(encodedBytes, encryptedData)
अगला, हम अपनी फ़ाइल सामग्री और अपने स्वयं के फ़ाइल प्रारूप को परिभाषित करते हैं। प्रारूप इस तरह दिखता है: salt[0x10]base64 content
। सबसे पहले, हम नमक को स्टोर करते हैं। बेस 64 सामग्री की शुरुआत को चिह्नित करने के लिए, हम बाइट 10
संग्रहीत करते हैं। यह काम करता है, क्योंकि बेस 64 इस मूल्य का उपयोग नहीं करता है। इसलिए, हम फ़ाइल के अंत से 10
की पहली घटना को खोजकर बेस 64 की शुरुआत पा सकते हैं।
fileContent := make([]byte, len(saltBytes))
copy(fileContent, saltBytes)
fileContent = append(fileContent, 10)
fileContent = append(fileContent, encodedBytes...)
चरण 10
अंत में, हम अपनी फाइल लिख सकते हैं: writeErr := ioutil.WriteFile("my secret.data", fileContent, 0644)
।
डिक्रिप्शन
परिचय और डेटा
एन्क्रिप्शन के लिए, हमें काम करने के लिए कुछ डेटा चाहिए। इस प्रकार, हम मानते हैं कि हमारे पास एक एन्क्रिप्टेड फ़ाइल और उल्लिखित संरचना secret
। लक्ष्य फ़ाइल से एन्क्रिप्ट किए गए डेटा को पढ़ना है, इसे डिक्रिप्ट करना है, और संरचना का एक उदाहरण बनाना है।
चरण 1
पहला चरण एन्क्रिप्शन के समान है: हमें गुप्त को डिक्रिप्ट करने के लिए एक प्रकार के मास्टर पासवर्ड की आवश्यकता होती है: masterPassword := "PASS"
।
चरण 2
अब, हम फ़ाइल से एन्क्रिप्टेड डेटा पढ़ते हैं: encryptedFileData, bytesErr := ioutil.ReadFile(filename)
।
चरण 3
जैसा कि पहले उल्लेख किया गया है, हम सीमांकित बाइट 10
द्वारा नमक और एन्क्रिप्टेड डेटा को विभाजित कर सकते हैं, अंत से शुरुआत तक पीछे की ओर खोजा गया है:
for n := len(encryptedFileData) - 1; n > 0; n-- {
if encryptedFileData[n] == 10 {
saltBytes = encryptedFileData[:n]
encryptedBytesBase64 = encryptedFileData[n+1:]
break
}
}
चरण 4
अगला, हमें आधार 64 एनकोडेड बाइट्स को डीकोड करना चाहिए:
decodedBytes := make([]byte, len(encryptedBytesBase64))
countDecoded, decodedErr := base64.StdEncoding.Decode(decodedBytes, encryptedBytesBase64)
encryptedBytes = decodedBytes[:countDecoded]
चरण 5
अब, हम RFC 2898 के बारे में मास्टर पासवर्ड और बेतरतीब नमक से एक कुंजी और एक वेक्टर प्राप्त करने में सक्षम हैं:
keyLength := 256
rfc2898Iterations := 6
keyVectorData := pbkdf2.Key(masterPassword, saltBytes, rfc2898Iterations, (keyLength/8)+aes.BlockSize, sha1.New)
keyBytes := keyVectorData[:keyLength/8]
vectorBytes := keyVectorData[keyLength/8:]
चरण 6
AES सिफर बनाएँ: aesBlockDecrypter, aesErr := aes.NewCipher(keyBytes)
।
चरण 7
डिक्रिप्ट किए गए डेटा के लिए आवश्यक मेमोरी को आरक्षित करें: decryptedData := make([]byte, len(encryptedBytes))
। परिभाषा के अनुसार, इसमें एन्क्रिप्टेड डेटा की लंबाई समान है।
चरण 8
अब, डिक्रिप्ट बनाएं और डेटा को डिक्रिप्ट करें:
aesDecrypter := cipher.NewCBCDecrypter(aesBlockDecrypter, vectorBytes)
aesDecrypter.CryptBlocks(decryptedData, encryptedBytes)
चरण 9
रीड बाइट्स को स्ट्रिंग में परिवर्तित करें: decryptedString := string(decryptedData)
। क्योंकि हमें लाइनों की आवश्यकता है, स्ट्रिंग को विभाजित करें: lines := strings.Split(decryptedString, "\n")
।
चरण 10
लाइनों के बाहर एक secret
निर्माण:
artifact := secret{}
artifact.DisplayName = lines[0]
artifact.Notes = lines[1]
artifact.Username = lines[2]
artifact.EMail = lines[3]
artifact.CopyMethod = lines[4]
artifact.Password = lines[5]
artifact.CustomField01Name = lines[6]
artifact.CustomField01Data = lines[7]
artifact.CustomField02Name = lines[8]
artifact.CustomField02Data = lines[9]
artifact.CustomField03Name = lines[10]
artifact.CustomField03Data = lines[11]
artifact.CustomField04Name = lines[12]
artifact.CustomField04Data = lines[13]
artifact.CustomField05Name = lines[14]
artifact.CustomField05Data = lines[15]
artifact.CustomField06Name = lines[16]
artifact.CustomField06Data = lines[17]
अंत में, नोट फ़ील्ड के भीतर लाइन ब्रेक को फिर से बनाएं: artifact.Notes = strings.Replace(artifact.Notes, string(65000), "\n", -1)
। नोट artifact.Notes = strings.Replace(artifact.Notes, string(65000), "\n", -1)
। नोट artifact.Notes = strings.Replace(artifact.Notes, string(65000), "\n", -1)
।