Cryptography in Go (Golang): Encryption and Hashing
Go (Golang) is a modern compiled language known for its performance and built-in support for cryptographic algorithms. The standard crypto library provides everything needed for data protection: from simple hashing to complex asymmetric encryption. In this article, we will cover the main tools and show practical code examples.
Why is cryptography needed in Go?
Cryptography in Go is used for:
- Storing passwords (hashing);
- Transmitting data over a network (TLS/SSL);
- Digital signatures and authentication;
- Encrypting confidential files.
Go guarantees security through a well-designed API — it is difficult to accidentally use an outdated or insecure algorithm.
Hashing in Go
Hashing is a one-way transformation of data into a fixed-length string. In Go, the packages crypto/md5, crypto/sha1, crypto/sha256, and crypto/sha512 handle this.
Example: SHA-256 hash
package main
import ( "crypto/sha256" "fmt")
func main() { data := []byte("Secret data") hash := sha256.Sum256(data) fmt.Printf("SHA256: %x", hash)}Output: SHA256: 3c3b... (64 characters)
Salting hashes for passwords
For secure password storage, use crypto/rand to generate a salt and crypto/sha256:
package main
import ( "crypto/rand" "crypto/sha256" "fmt")
func main() { password := []byte("MyPassword123") salt := make([]byte, 16) rand.Read(salt) salted := append(salt, password...) hash := sha256.Sum256(salted) fmt.Printf("Salt: %x", salt) fmt.Printf("Hash: %x", hash)}In practice, it is better to use bcrypt (package golang.org/x/crypto/bcrypt) for passwords, but SHA-256 with a salt is a good option for learning.
Symmetric encryption: AES
AES (Advanced Encryption Standard) is the most popular symmetric algorithm. In Go, it is implemented in the crypto/aes package in conjunction with encryption modes (crypto/cipher).
Example: AES-GCM encryption
package main
import ( "crypto/aes" "crypto/cipher" "crypto/rand" "fmt")
func main() { key := []byte("0123456789abcdef0123456789abcdef") // 32 bytes for AES-256 plaintext := []byte("Confidential message") block, _ := aes.NewCipher(key) aead, _ := cipher.NewGCM(block) nonce := make([]byte, aead.NonceSize()) rand.Read(nonce) ciphertext := aead.Seal(nil, nonce, plaintext, nil) fmt.Printf("Encrypted: %x", ciphertext) // Decryption decrypted, _ := aead.Open(nil, nonce, ciphertext, nil) fmt.Printf("Decrypted: %s", decrypted)}GCM (Galois/Counter Mode) provides confidentiality and authentication — the best choice for most tasks.
Asymmetric encryption: RSA
RSA uses a pair of keys (public and private). In Go, it is implemented in crypto/rsa and crypto/rand.
Key generation and encryption
package main
import ( "crypto/rand" "crypto/rsa" "crypto/sha256" "fmt")
func main() { privateKey, _ := rsa.GenerateKey(rand.Reader, 2048) publicKey := &privateKey.PublicKey message := []byte("Secret for RSA") label := []byte("") // Encryption with public key ciphertext, _ := rsa.EncryptOAEP(sha256.New(), rand.Reader, publicKey, message, label) fmt.Printf("Encrypted RSA: %x", ciphertext) // Decryption with private key plaintext, _ := rsa.DecryptOAEP(sha