Around Go: service security · 3 MIN READ
Passwords, MACs and randomness solve different problems
Choose purpose-specific primitives and bound their cost instead of inventing cryptography.
A fast hash, password hash, MAC, encryption scheme and digital signature answer different questions. A SHA-256 digest does not make a password database resistant to guessing, and encryption without authentication can accept altered ciphertext. Use reviewed libraries and document the purpose, key lifetime, input format and resource budget before selecting a primitive.
security · A MAP OF THE IDEA
- Define purpose
- Use reviewed primitive
- Manage key + cost
- Test hostile inputs
Useful when
- Choose purpose-specific primitives and bound their cost instead of inventing cryptography.
- Makes the owner and the failure boundary explicit.
Watch out
- Do not use math/rand for secrets, a fast unsalted digest for password storage, or a plain equality loop for secret MAC tags.
- Run native service and failure tests in your own development environment.
Implementation & operation cost: Additional state and tests must be justified by the demonstrated failure; this lesson is not a requirement for every Go program.
The contract and the failure
A fast hash, password hash, MAC, encryption scheme and digital signature answer different questions. A SHA-256 digest does not make a password database resistant to guessing, and encryption without authentication can accept altered ciphertext. Use reviewed libraries and document the purpose, key lifetime, input format and resource budget before selecting a primitive.
Work through the example
Use an appropriate reviewed password KDF such as Argon2id where your policy permits it, with random salt and stored algorithm/version/cost parameters. Benchmark memory and CPU cost under concurrent login load and bound admission; expensive verification is also a denial-of-service surface. For secret encryption prefer a reviewed authenticated construction and a key/nonce management design instead of assembling low-level primitives.
package main
import (
"crypto/hmac"
"crypto/rand"
"crypto/sha256"
"fmt"
)
func tag(key, message []byte) []byte {
m := hmac.New(sha256.New, key)
_, _ = m.Write(message)
return m.Sum(nil)
}
func main() {
key := make([]byte, 32)
if _, err := rand.Read(key); err != nil {
panic(err)
}
message := []byte("action=read;resource=7")
expected := tag(key, message)
fmt.Println(hmac.Equal(expected, tag(key, message))) // true
fmt.Println(hmac.Equal(expected, tag(key, []byte("action=write;resource=7")))) // false
// Never print key material; a MAC does not hide the message.
}The secret key comes from crypto/rand rather than a predictable simulation PRNG. HMAC authenticates these exact bytes and hmac.Equal performs the intended tag comparison. This example has no expiry, replay store or message canonicalization policy, so it is not by itself a complete access-token protocol.
Production decisions
Do not use math/rand for secrets, a fast unsalted digest for password storage, or a plain equality loop for secret MAC tags. Do not copy one parameter value forever from a tutorial. Test corrupted tags, wrong keys, duplicate/replayed messages, unsupported KDF parameters and resource exhaustion. Keep production keys outside code and logs, and define rotation and recovery procedures.
Explain it in an interview
Does an HMAC both hide its message and prevent the same message being replayed? No. A MAC authenticates bytes; confidentiality, expiry, replay prevention and key lifecycle require separate protocol decisions. Describe the state before the operation, its owner, the failure between steps and the evidence you would test. Distinguish what this example demonstrates from the infrastructure a production service still needs.
TAKE THIS WITH YOU
Choose purpose-specific primitives and bound their cost instead of inventing cryptography. No. A MAC authenticates bytes; confidentiality, expiry, replay prevention and key lifecycle require separate protocol decisions.
Check your understanding
Does an HMAC both hide its message and prevent the same message being replayed?
Go to the source
Progress stays in this browser. No account needed.