Practical SSL/TLS and Cryptography Guide Using Go and kubeadm
This article provides a comprehensive walkthrough of using Go's crypto library for hashing, symmetric and asymmetric encryption, certificate generation, and TLS/HTTPS server and client implementation, illustrating how these techniques are applied in kubeadm to simplify Kubernetes cluster security.
This guide explains how to leverage Go's standard crypto package for common security tasks such as computing file hashes, performing symmetric and asymmetric encryption, generating certificates, and building TLS/HTTPS services, with a focus on Kubernetes automation via kubeadm .
File hash calculation – For small files you can import the hash algorithms and read the file contents directly:
import (
"crypto/md5"
"crypto/sha1"
"crypto/sha256"
"crypto/sha512"
"fmt"
"io/ioutil"
)
data, err := ioutil.ReadFile(filename)
fmt.Printf("Md5: %x\n", md5.Sum(data))
fmt.Printf("Sha1: %x\n", sha1.Sum(data))
fmt.Printf("Sha256: %x\n", sha256.Sum256(data))
fmt.Printf("Sha512: %x\n", sha512.Sum512(data))For large files a streaming approach with an io.Reader and a hash writer is used:
file, err := os.Open(filename)
hasher := md5.New()
_, err = io.Copy(hasher, file)
checksum := hasher.Sum(nil)Symmetric encryption (AES) – The example creates a random IV, encrypts a message with AES in CFB mode, and returns the ciphertext:
import (
"crypto/aes"
"crypto/cipher"
"crypto/rand"
"io"
)
func encrypt(key, message []byte) ([]byte, error) {
block, err := aes.NewCipher(key)
cipherText := make([]byte, aes.BlockSize+len(message))
iv := cipherText[:aes.BlockSize]
_, err = io.ReadFull(rand.Reader, iv)
cfb := cipher.NewCFBEncrypter(block, iv)
cfb.XORKeyStream(cipherText[aes.BlockSize:], message)
return cipherText, nil
}Decryption mirrors the process using cipher.NewCFBDecrypter :
func decrypt(key, cipherText []byte) ([]byte, error) {
block, err := aes.NewCipher(key)
iv := cipherText[:aes.BlockSize]
cipherText = cipherText[aes.BlockSize:]
cfb := cipher.NewCFBDecrypter(block, iv)
cfb.XORKeyStream(cipherText, cipherText)
return cipherText, nil
}Asymmetric encryption (RSA) and signing – Keys are generated with rsa.GenerateKey , PEM‑encoded, and stored. Signing uses rsa.SignPKCS1v15 on a SHA‑256 hash of the message, while verification uses rsa.VerifyPKCS1v15 :
import (
"crypto"
"crypto/rand"
"crypto/rsa"
"crypto/sha256"
"crypto/x509"
"encoding/pem"
"io/ioutil"
)
// Load private key from PEM file
func loadPrivateKeyFromPemFile(fname string) *rsa.PrivateKey {
data, _ := ioutil.ReadFile(fname)
block, _ := pem.Decode(data)
key, _ := x509.ParsePKCS1PrivateKey(block.Bytes)
return key
}
// Sign a message
hashed := sha256.Sum256(message)
signature, _ := rsa.SignPKCS1v15(rand.Reader, privateKey, crypto.SHA256, hashed[:])Certificate generation – A self‑signed X.509 certificate is built by creating a pkix.Name template, filling fields such as organization, common name, and validity period, then calling x509.CreateCertificate with the private key:
certTemplate := x509.Certificate{
SerialNumber: randomNumber,
Subject: pkix.Name{Organization: []string{"My Organization"}, CommonName: "localhost"},
NotBefore: time.Now(),
NotAfter: time.Now().Add(365 * 24 * time.Hour),
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageAny},
BasicConstraintsValid: true,
}
certDER, _ := x509.CreateCertificate(rand.Reader, &certTemplate, &certTemplate, &privKey.PublicKey, privKey)
writeCertToPemFile("cert.pem", certDER)TLS server example – Loads the certificate/key pair, configures a tls.Config , and listens for TCP connections, echoing received data back to the client:
serverCert, _ := tls.LoadX509KeyPair(certFilename, privKeyFilename)
config := &tls.Config{Certificates: []tls.Certificate{serverCert}}
listener, _ := tls.Listen("tcp", hostString, config)
for {
conn, _ := listener.Accept()
go handleConnection(conn)
}HTTPS server – Uses the standard net/http package with ListenAndServeTLS to serve a simple handler over TLS:
func indexHandler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "You requested: %s", r.URL.Path)
}
http.HandleFunc("/", indexHandler)
http.ListenAndServeTLS("localhost:8181", "cert.pem", "privateKey.pem", nil)TLS client with custom CA – Configures a client to trust a self‑signed CA, presents its own certificate, and performs a GET request to the HTTPS server:
pair, _ := tls.LoadX509KeyPair("client.crt", "client.key")
client := &http.Client{Transport: &http.Transport{TLSClientConfig: &tls.Config{RootCAs: loadCA("ca.crt"), Certificates: []tls.Certificate{pair}}}}
resp, _ := client.Get("https://localhost")
io.Copy(os.Stdout, resp.Body)In summary, the article demonstrates practical Go code for hashing, symmetric and asymmetric encryption, X.509 certificate creation, and building TLS/HTTPS services, which are the building blocks used by kubeadm to automate secure Kubernetes cluster deployment.
360 Tech Engineering
Official tech channel of 360, building the most professional technology aggregation platform for the brand.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.