수색…


소개

Go로 데이터를 암호화하고 해독하는 방법을 알아보십시오. 이것은 암호에 관한 과정이 아니라 Go로이를 달성하는 방법입니다.

암호화 및 해독

머리말

Go로 데이터를 암호화하고 해독하는 방법에 대한 자세한 예제입니다. 사용 코드가 짧아집니다. 예를 들어 오류 처리가 언급되지 않았습니다. 오류 처리 및 사용자 인터페이스가있는 전체 작업 프로젝트는 여기 Github 에서 찾을 수 있습니다.


암호화

소개 및 데이터

이 예제는 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 을 암호화하려고합니다. 전체 작업 예제는 여기 에서 찾을 수 있습니다 (Github에 대한 링크) . 이제는 단계별 프로세스입니다.

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 단계

레인보우 테이블 공격을 방지하기 위해 소금을 만듭니다. Wikipedia : 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 단계

원하는 CBC 모드는 전체 블록에서 작동합니다. 따라서 데이터가 전체 블록에 정렬되어 있는지 확인해야합니다. 그렇지 않다면, 우리는 그것을 채워 넣어야합니다 :

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)) . AES-CBC의 경우 암호화 된 데이터의 길이는 암호화되지 않은 데이터의 길이와 동일합니다.

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 . 먼저 소금을 저장합니다. base64 내용의 시작을 표시하기 위해 바이트 10 저장합니다. base64는이 값을 사용하지 않으므로이 방법이 효과적입니다. 그러므로 우리는 파일의 끝에서부터 시작까지 10 의 첫 번째 발생을 검색하여 base64의 시작을 찾을 수 있습니다.

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 단계

다음으로 base64로 인코딩 된 바이트를 디코딩해야합니다.

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 단계

이제 decrypter를 만들고 데이터의 암호를 해독합니다.

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]

마지막으로 notes 필드에 줄 바꿈을 다시 작성하십시오. artifact.Notes = strings.Replace(artifact.Notes, string(65000), "\n", -1) .



Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow