GOlang ile şifreleme işlemleri için crypto paketi
Tags: go, crypto, hash, encryption
Published: 2023-01-14 10:38:28

GOlang üzerinde kriptografik işlemleri yapabilmek için kendi içerisinde çeşitli fonksiyonları içeren [açık kaynak kodlu](https://github.com/golang/crypto) "**crypto**" paketi bulunmaktadır. 

İlgili paket özellikle çeşitli hash, anahtar ve imzalama işlemlerini barındırarak bunlara uygun "type" değerlerini ve "fonksiyonları" barındırmaktadır.

Paket hakkında en güzel bilgi ve temel örnekler kendi [belgelendirme sayfası](https://pkg.go.dev/crypto)nda olmasına rağmen bazı kavramları özetlemek istiyorum.

# Hash tanımları

Kendi içerisinde varsayılan olarak MD5 ve SHA1..512 uyarlamalarını barındırmaktadır. Dolayısıyla herhangi bir noktada bunlara ihtiyacınız olduğunda oldukça kolay kullanabilirsiniz.

# Paket bileşenleri

Paket içerisinde bir çok uyarlama bulunmaktadır. Bunların listesi aşağıdaki gibi olmakla birlikte bu uyarlamaların altında bir çok hazır fonksiyon da bulunmaktadır. 

- aes 
- cipher
- des
- dsa
- ecdsa
- ed25519
- elliptic
- hmac
- md5
- rand
- rc4
- rsa
- sha1
- sha256
- sha512
- subtle
- tls
- x509 - pkix

Bu hazır uyarlamalar ile GOlang ile çeşitli kriptografik işlemleri yapabilirsiniz.

Bu kütüphaneyi kullanırken özellikle [encoding](https://pkg.go.dev/encoding) paketini de kullanmak özellikle hex, string ve byte dönüşümleri oldukça önemli olmaktadır. 

# Basit bir hash örneği

Bir verinin hash olarak saklanması için kullanılabilecek aşağıdaki örnek ile GOlang üzerinde basitçe hash kullanımı sağlanabilmektedir. Bu örnekte saklanacak bir verinin MD5 dönüşümü ile çevrimi gösterilmektedir. 

```go
package main

import (
	"crypto/md5"
	"encoding/hex"
	"fmt"
)

func getMD5Hash(message string) string {
	hash := md5.Sum([]byte(message))
	return hex.EncodeToString(hash[:])
}

func main() {
	password := "saklanacakveri"
	fmt.Println("MD5 hashli değeri: ", getMD5Hash(password))
}
```

Genel kullanım alanı tek yönlü şekilde parolaların bir yerlerde saklanabilmesini sağlamak diye düşünebiliriz. Ve en önemli noktası geri dönüşümünün olmaması. Bunun yanında deneme-yanılma ataklarıyla "tuzlama" olarak ifade edilen şekilde, ek bir veri kullanmadan direkt hash kullanımı ile saldırı yapılabilmektedir.

# Basit bir AES şifreleme örneği

Bu kütüphaneyi kullanarak bir mesajı basit bir şekilde şifrelemek için aşağıdaki gibi fonksiyonlar tanımlayabilirsiniz. Hash örneğinden farklı olarak anahtar yardımı ile geri dönüşümü yapılabilmektedir.

```go
package main

import (
	"crypto/aes"
	"encoding/hex"
	"fmt"
)

func encryptMessage(key string, message string) string {
	c, err := aes.NewCipher([]byte(key))
	if err != nil {
		fmt.Println(err)
	}
	msgByte := make([]byte, len(message))
	c.Encrypt(msgByte, []byte(message))
	return hex.EncodeToString(msgByte)
}

func main() {
	plainText := "Ornek Mesaj"                  
	key := "this_must_be_of_32_byte_length!!"

	sifrelimesaj := encryptMessage(key, plainText)
	fmt.Println("Şifrlenmiş Mesaj: ", sifrelimesaj)
}

```

Yukarıdaki gibi bir fonksiyon ile, belirli bir anahtar kullanılarak bir mesajın şifrelenmesini görebilirsiniz.

Aynı şifrenin, yine aynı anahtar değeri ile açılması için ise aşağıdaki fonksiyonun da tanımlanması gerekmektedir.

```go
func decryptMessage(key string, message string) string {
	txt, _ := hex.DecodeString(message)
	c, err := aes.NewCipher([]byte(key))
	if err != nil {
		fmt.Println(err)
	}
	msgByte := make([]byte, len(txt))
	c.Decrypt(msgByte, []byte(txt))

	msg := string(msgByte[:])
	return msg
}
```

Ve yukarıdaki şifreli mesajın, main fonksiyonunda tekrardan decrypt edilmesi sağlanmalıdır.

```go
cozulmusmesaj := decryptMessage(key, sifrelimesaj)
fmt.Println("Çözülmüş Mesaj: ", cozulmusmesaj)
```

Bu şekilde crypto paketi ile şifrelenebilen ve çözülebilen bir yapı kurulabilmesi sağlanmaktadır. Tabi ki kriptolojik olarak buradaki şifreleme işlemini daha farklı algoritmalarla daha zorlaştırabilir, belirli standartlar kullanarak da bunların farklı ortamlarla entegre olabilmesini sağlayabilirsiniz.