skip to content

Security and Cryptography

Go puts the crypto in the standard library, so the question is never which library but which call: crypto/rand over math/rand, subtle over ==, and a tls.Config you mostly leave alone.

part ofGo (Golang)overview, primer and where to startread it →
on this pageshow

explore

questions

80 · 4 sections

How do you build an AES-GCM cipher.AEAD in Go and encrypt one message with it?

level: juniorimportance: must knowfreq 50%
basics
~10 s

Pass the key to aes.NewCipher to get a cipher.Block, wrap that block with cipher.NewGCM to get a cipher.AEAD, then call Seal(dst, nonce, plaintext, additionalData). Seal returns the ciphertext with a 16-byte authentication tag appended.

open as a page

What does Go's hmac.Equal do that bytes.Equal does not, and what does it return?

level: juniorimportance: must knowfreq 45%
basics
~20 s

hmac.Equal(mac1, mac2 []byte) returns a bool and scans every byte, so its running time does not depend on the contents. bytes.Equal stops at the first differing byte, so its timing reveals how much of the input matched.

open as a page

What is the difference between sha256.Sum256 and sha256.New, and when do you use each?

level: juniorimportance: must knowfreq 52%
basics
~20 s

sha256.Sum256 hashes a byte slice you already hold and returns a [32]byte array. sha256.New returns a streaming hash.Hash you write data into and finish with Sum(nil) - use that when the input is a file or stream too large to buffer.

open as a page

How do you use `hkdf.Key` in Go to turn one master secret into a separate key per purpose?

level: juniorimportance: must knowfreq 45%
basics
~10 s

Call hkdf.Key once per purpose with a different info string each time, for example "cookie-encryption-v1" versus "url-signing-v1". Same secret, same salt, different info, and you get independent keys you never have to store.

open as a page

Why is math/rand/v2 unsafe for generating a password-reset token in Go, and what do you use instead?

level: juniorimportance: must knowfreq 62%
basics
~20 s

math/rand/v2 is a statistical generator that makes no unpredictability promise, so its output can be reconstructed no matter how it is seeded. Use crypto/rand instead: rand.Text() for a token string, or crypto/rand.Read to fill a byte slice.

open as a page

What does x509.CreateCertificate return in Go, and what must you do before writing a .crt file?

level: juniorimportance: must knowfreq 40%
basics
~10 s

x509.CreateCertificate returns the signed certificate as raw DER bytes, not a file and not text. To get a .crt or .pem file, wrap those bytes with encoding/pem in a block whose Type is CERTIFICATE.

open as a page

In Go, how do you tell an unset environment variable from one set to an empty string when loading a credential?

level: juniorimportance: must knowfreq 70%
basics
~20 s

os.Getenv returns an empty string for both cases, so it cannot tell them apart. os.LookupEnv returns the value plus a boolean that is false only when the variable is absent, letting you fail startup instead of running with an empty credential.

open as a page

In Go, how do you turn the bytes of a PEM certificate file into an *x509.Certificate?

level: juniorimportance: must knowfreq 48%
basics
~10 s

Call pem.Decode on the file bytes, check the returned block is non-nil and its Type is CERTIFICATE, then pass block.Bytes, which is the DER, to x509.ParseCertificate. Both steps can fail; check both.

open as a page

Why must a certificate you issue in Go set DNSNames rather than only Subject.CommonName?

level: middleimportance: must knowfreq 44%
basics
~20 s

Hostname checking reads the Subject Alternative Name extension, which the template fills from DNSNames, IPAddresses, URIs and EmailAddresses. Go's verifier stopped matching Subject.CommonName in Go 1.15, so a certificate carrying the hostname only in CommonName is rejected.

open as a page

A Go reload goroutine assigns a new *tls.Certificate that GetCertificate reads — why does -race flag it?

level: middleimportance: must knowfreq 50%
basics
~20 s

Two goroutines touch one variable with no synchronisation: the reloader writes the pointer while handshake goroutines read it. A pointer-sized write is not automatically ordered in Go. Keep the certificate in an atomic.Pointer and Load it inside the callback.

open as a page

How do you serve HTTPS from a Go net/http server, and where does a tls.Config go?

level: juniorimportance: must knowfreq 58%
basics
~20 s

Call ListenAndServeTLS with a certificate file and a key file. The package-level http.ListenAndServeTLS takes no tls.Config, so to set TLS options you build an http.Server, fill its TLSConfig field, and call that server's ListenAndServeTLS method.

open as a page

Which tls.Config fields make a Go TLS server require and verify a client certificate?

level: juniorimportance: must knowfreq 42%
basics
~10 s

Two fields on the server's tls.Config: ClientCAs, an x509.CertPool of the CAs you trust to issue client certificates, and ClientAuth set to tls.RequireAndVerifyClientCert. ClientCAs alone asks for nothing and verifies nothing.

open as a page

What does tls.Config.InsecureSkipVerify = true actually turn off in a Go TLS client?

level: juniorimportance: must knowfreq 58%
basics
~20 s

It turns off both checks a Go TLS client makes on the peer's certificate: the chain is no longer verified against any trust root, and the name in the certificate is no longer matched. Any certificate from anyone is accepted.

open as a page

Since Go 1.24, which key exchange does crypto/tls prefer by default, and why is it a hybrid?

level: juniorimportance: should knowfreq 30%
basics
~10 s

Go 1.24 made X25519MLKEM768 the preferred TLS 1.3 key exchange whenever tls.Config.CurvePreferences is left nil. It is hybrid: classical X25519 runs alongside post-quantum ML-KEM-768, so the session key holds if either half survives.

open as a page

What does tls.Config.MinVersion control, and what applies when you leave it at zero?

level: middleimportance: should knowfreq 50%
basics
~20 s

tls.Config.MinVersion is the oldest TLS protocol version Go will negotiate; older peers are refused during the handshake. Zero means the crypto/tls package default, TLS 1.2 in current Go. Set it explicitly, because that default has been raised across releases.

open as a page

What does the Go checksum database at sum.golang.org guarantee that go.sum alone cannot?

level: middleimportance: must knowfreq 55%
basics
~20 s

go.sum only pins the bytes your machine saw first, so a poisoned first download is pinned faithfully forever. The checksum database is a global append-only log of module hashes that the go command consults before writing a new go.sum line.

open as a page

What can a Go dependency's init functions and package-level variables do to every binary that imports it?

level: middleimportance: must knowfreq 55%
basics
~20 s

Anything. Package-level variable initializers and every init function in an imported package run before main, in every binary that pulls the package in, directly or transitively. You cannot import a package and skip them, so whatever they do is imposed on your program.

open as a page

Why does Go's symbol-level vulnerability analysis report fewer findings than a go.mod manifest scan?

level: middleimportance: must knowfreq 55%
basics
~20 s

Because it matches called symbols, not module versions. Go's analysis builds a static call graph and reports an advisory only when a path in your program reaches one of the vulnerable functions. A manifest scan flags every affected version you require.

open as a page

What does `go mod verify` actually check, and what does a passing result not prove?

level: juniorimportance: should knowfreq 44%
basics
~20 s

go mod verify recomputes hashes of the dependencies in your local module cache and compares them with the hashes recorded at download time. It proves nobody edited the cache since; it does not re-download, contact the checksum database, or find vulnerabilities.

open as a page

Which go command shows why a module you never required is in your build, and what does it print?

level: juniorimportance: should knowfreq 45%
basics
~20 s

go mod why -m <module> prints the shortest chain of package imports leading from your main module to that module. If nothing in your build imports it, the command reports that the main module does not need it.

open as a page