crypto/rand.Read în Go

Umple un slice cu octeți aleatorii siguri criptografic, luați de la sistemul de operare (chei, tokenuri, sare).

Sintaxă
import "crypto/rand"

func Read(b []byte) (n int, err error)

Ce face crypto/rand.Read

rand.Read(b) umple tot slice-ul b cu octeți aleatorii imprevizibili, potriviți pentru securitate: chei de criptare, tokenuri de sesiune, coduri de resetare a parolei, „sare” pentru hash-uri. Sursa este generatorul sistemului de operare.

Din Go 1.24, funcția nu returnează niciodată eroare și umple mereu tot slice-ul (dacă sistemul nu poate da octeți aleatorii, programul se oprește). Semnătura păstrează (n, err) pentru compatibilitate. Pentru un text gata de folosit există rand.Text().

Nu confunda cu math/rand/v2: acela este rapid și bun pentru jocuri și simulări, dar valorile lui pot fi ghicite, deci nu se folosește pentru securitate.

Parametri

Parametru Descriere
b Slice-ul de umplut; lungimea lui stabilește câți octeți primești.

Ce returnează

Numărul de octeți (len(b)) și o eroare (întotdeauna nil din Go 1.24).

Exemple

Exemplul 1: Cheie de 32 de octeți

Afișăm doar proprietăți care nu depind de valori: lungimea cheii și a textului hex.

package main

import (
	"crypto/rand"
	"encoding/hex"
	"fmt"
)

func main() {
	cheie := make([]byte, 32) // 256 de biți, pentru AES-256
	n, err := rand.Read(cheie)
	fmt.Println("Octeți primiți:", n, "eroare:", err)
	fmt.Println("Lungime hex:", len(hex.EncodeToString(cheie)))

	alta := make([]byte, 32)
	rand.Read(alta)
	fmt.Println("Două chei identice:", hex.EncodeToString(cheie) == hex.EncodeToString(alta))
}

Rezultat

Octeți primiți: 32 eroare: <nil>
Lungime hex: 64
Două chei identice: false

Exemplul 2: Token de resetare a parolei

Valorile diferă la fiecare rulare.

package main

import (
	"crypto/rand"
	"encoding/base64"
	"fmt"
)

func main() {
	b := make([]byte, 24)
	rand.Read(b)
	token := base64.RawURLEncoding.EncodeToString(b)
	fmt.Println("https://magazin.ro/resetare?token=" + token)
}

Rezultat posibil (diferă la fiecare rulare)

https://magazin.ro/resetare?token=q3Vx9H0dQm7kT2yLwR8bZcJ1fNaE4sPu

Greșeli frecvente

  • Generezi tokenuri sau parole cu math/rand: un atacator poate reconstrui starea generatorului și poate ghici valorile. Folosește crypto/rand.
  • Creezi slice-ul cu make([]byte, 0, 32): are lungimea 0, deci Read nu pune nimic în el. Lungimea trebuie să fie 32.

Comenzi înrudite

  • crypto/rand.Text: Returnează un text aleatoriu sigur (26 de caractere A-Z și 2-7, cel puțin 128 de biți), gata de folosit ca token sau secret.
  • crypto/rand.Int: Returnează un număr aleatoriu sigur, uniform în intervalul [0, max), ca *big.Int; bun pentru coduri PIN și OTP.
  • encoding/base64.Encoding: Codează octeți ca text Base64 (litere, cifre, +/ sau -_); StdEncoding, URLEncoding și variantele Raw fără „=”.
  • encoding/hex.EncodeToString: Scrie octeții în hexazecimal (două cifre 0-9a-f pe octet) și înapoi; forma obișnuită pentru hash-uri și chei.