Information Security 18 min read

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.

360 Tech Engineering
360 Tech Engineering
360 Tech Engineering
Practical SSL/TLS and Cryptography Guide Using Go and kubeadm

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.

kubernetesGohashingTLScryptographyCertificates
360 Tech Engineering
Written by

360 Tech Engineering

Official tech channel of 360, building the most professional technology aggregation platform for the brand.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.