crypto

package
v0.0.7 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 18, 2026 License: MIT Imports: 16 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrInvalidKeyLength se retorna cuando la clave de cifrado no tiene
	// la longitud correcta. AES-256 requiere exactamente 32 bytes.
	ErrInvalidKeyLength = errors.New("la clave debe tener exactamente 32 bytes para AES-256")

	// ErrEncryptionFailed se retorna cuando el proceso de cifrado falla.
	// Es un error genérico que no revela detalles internos del sistema.
	ErrEncryptionFailed = errors.New("fallo al cifrar los datos")

	// ErrDecryptionFailed se retorna cuando el proceso de descifrado falla.
	// Puede deberse a una clave incorrecta, datos corruptos o manipulación.
	ErrDecryptionFailed = errors.New("fallo al descifrar los datos")

	// ErrInvalidCiphertext se retorna cuando el texto cifrado está mal formado
	// o no tiene el formato esperado (nonce + ciphertext + tag).
	ErrInvalidCiphertext = errors.New("formato de texto cifrado inválido")
)
View Source
var (
	// ErrInvalidHash se retorna cuando el formato del hash no cumple con la especificación PHC
	// o no puede ser interpretado por ningún parser.
	ErrInvalidHash = errors.New("formato de hash inválido")

	// ErrUnsupportedAlgorithm se retorna al solicitar un algoritmo no registrado o no disponible.
	ErrUnsupportedAlgorithm = errors.New("algoritmo de hashing no soportado")

	// ErrPasswordTooShort se retorna si la contraseña no cumple el tamaño mínimo seguro.
	ErrPasswordTooShort = errors.New("la contraseña es demasiado corta")

	// ErrPasswordTooLong se retorna si la contraseña excede el tamaño máximo permitido (mitiga DoS).
	ErrPasswordTooLong = errors.New("la contraseña es demasiado larga")
)
View Source
var (
	// ErrInvalidLength se retorna cuando se solicita una longitud inválida
	// (negativa o cero) para la generación de datos aleatorios.
	ErrInvalidLength = errors.New("la longitud debe ser mayor que cero")

	// ErrRandomGenerationFailed se retorna cuando el generador criptográfico
	// del sistema no puede producir datos aleatorios (fallo muy raro pero posible).
	// Es un error genérico que no revela detalles internos del sistema.
	ErrRandomGenerationFailed = errors.New("fallo al generar datos aleatorios seguros")

	// ErrInvalidPrefix se retorna cuando el prefijo proporcionado a GenerateAPIKey
	// contiene caracteres no alfanuméricos.
	ErrInvalidPrefix = errors.New("el prefijo debe ser alfanumérico")
)

Functions

func DecryptBytes

func DecryptBytes(ciphertext string) ([]byte, error)

DecryptBytes descifra bytes usando AES-256-GCM con la clave por defecto.

Ejemplo:

plaintext, err := crypto.DecryptBytes(ciphertext)

func DecryptString

func DecryptString(ciphertext string) (string, error)

DecryptString descifra un string usando AES-256-GCM con la clave por defecto.

Ejemplo:

plaintext, err := crypto.DecryptString(ciphertext)

func DecryptWithKey

func DecryptWithKey(ciphertext string, key []byte) (string, error)

DecryptWithKey descifra datos usando una clave específica (sin usar global).

func EncryptBytes

func EncryptBytes(plaintext []byte) (string, error)

EncryptBytes cifra bytes usando AES-256-GCM con la clave por defecto.

Ejemplo:

ciphertext, err := crypto.EncryptBytes([]byte("datos-binarios"))

func EncryptString

func EncryptString(plaintext string) (string, error)

EncryptString cifra un string usando AES-256-GCM con la clave por defecto. ADVERTENCIA: La clave por defecto NO es segura para producción. Usa SetEncryptionKey() o NewAESEncrypter() para producción.

Ejemplo:

ciphertext, err := crypto.EncryptString("dato-secreto")

func EncryptWithKey

func EncryptWithKey(plaintext string, key []byte) (string, error)

EncryptWithKey cifra datos usando una clave específica (sin usar global).

func GenerateAPIKey

func GenerateAPIKey(prefix string) (string, error)

GenerateAPIKey genera una API key con el formato: "prefijo_stringHex". El prefijo ayuda a identificar el tipo de clave sin revelar información sensible, y el string hexadecimal proporciona la entropía necesaria.

Si prefix está vacío, se usa el prefijo por defecto "gk". La longitud del string hexadecimal es de 32 bytes (64 caracteres).

Ejemplo de uso:

apiKey := crypto.GenerateAPIKey("usr")
// Resultado: "usr_a1b2c3d4e5f6..."

apiKey := crypto.GenerateAPIKey("")
// Resultado: "gk_a1b2c3d4e5f6..." (prefijo por defecto)

func GenerateAPIKeyWithPrefix

func GenerateAPIKeyWithPrefix(prefix string) (string, error)

GenerateAPIKey genera una API key con formato "prefijo_hex".

func GenerateEncryptionKey

func GenerateEncryptionKey() ([]byte, error)

GenerateEncryptionKey genera una clave criptográficamente segura de 32 bytes (256 bits) para usar con AES-256. Esta clave debe mantenerse en secreto y almacenarse de forma segura (ej. variables de entorno, vault, KMS).

IMPORTANTE: Si pierdes esta clave, los datos cifrados con ella serán irrecuperables. No hay forma de recuperar la clave.

Ejemplo de uso:

key, err := crypto.GenerateEncryptionKey()
if err != nil {
    // Manejar error (fallo del sistema, muy raro)
}

// Guardar la clave de forma segura
// Ejemplo: os.Setenv("ENCRYPTION_KEY", base64.StdEncoding.EncodeToString(key))

// Usar la clave para crear un cifrador
encrypter, _ := crypto.NewAESEncrypter(key)

func GenerateEncryptionKeyBase64

func GenerateEncryptionKeyBase64() (string, error)

GenerateEncryptionKeyBase64 genera una clave de cifrado y la devuelve codificada en base64 para facilitar su almacenamiento en variables de entorno o archivos de configuración.

Ejemplo de uso:

keyBase64, err := crypto.GenerateEncryptionKeyBase64()
if err != nil {
    // Manejar error
}
fmt.Println(keyBase64) // "r4nd0mK3yB4s364..."

// Para usarla después:
key, _ := base64.StdEncoding.DecodeString(keyBase64)
encrypter, _ := crypto.NewAESEncrypter(key)

func GenerateNumericCode

func GenerateNumericCode(length int) (string, error)

GenerateNumericCode genera un código numérico de la longitud especificada. Usa crypto/rand para garantizar que el código sea impredecible.

Ideal para:

  • OTPs enviados por SMS o email
  • Códigos de verificación de 2FA
  • PINs temporales
  • Códigos de recuperación

Ejemplo de uso:

code, err := crypto.GenerateNumericCode(6)
if err != nil {
    // Manejar error
}
// Resultado: "482913" (6 dígitos)

// Para códigos más largos (ej. recuperación):
code, _ := crypto.GenerateNumericCode(8)
// Resultado: "94827163"

func GenerateOTP

func GenerateOTP(length int) (string, error)

GenerateOTP genera un código numérico OTP de longitud especificada.

func GenerateRandomBytes

func GenerateRandomBytes(n int) ([]byte, error)

GenerateRandomBytes genera n bytes criptográficamente seguros.

func GenerateRandomString

func GenerateRandomString(n int) (string, error)

GenerateRandomString genera un string aleatorio URL-safe de n caracteres.

func GenerateSecureToken

func GenerateSecureToken() (string, error)

GenerateSecureToken genera un token hexadecimal de 32 bytes (64 chars).

func GenerateUUID

func GenerateUUID() (string, error)

GenerateUUID genera un UUID versión 4 (aleatorio) según RFC 4122. Los UUID v4 son ideales para identificadores únicos distribuidos donde no se requiere centralización ni secuencialidad.

Formato: xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx Donde:

  • El dígito '4' indica versión 4
  • 'y' es uno de [8, 9, a, b] (variante RFC 4122)

Ejemplo de uso:

id := crypto.GenerateUUID()
// Resultado: "550e8400-e29b-41d4-a716-446655440000"

func GenerateUUIDv4

func GenerateUUIDv4() (string, error)

GenerateUUIDv4 genera un UUID versión 4 aleatorio.

func HashPassword

func HashPassword(password string) (string, error)

HashPassword genera un hash seguro de contraseña usando Argon2id (por defecto). Es la forma más rápida de hashear contraseñas sin configuración.

Ejemplo:

hash, err := crypto.HashPassword("mi-contraseña")

func HashWithArgon2id

func HashWithArgon2id(password string) (string, error)

HashWithArgon2id genera un hash usando Argon2id con configuración óptima. Recomendado para la mayoría de casos (OWASP).

func HashWithBcrypt

func HashWithBcrypt(password string) (string, error)

HashWithBcrypt genera un hash usando Bcrypt con costo 12. Bueno para compatibilidad con sistemas legacy.

func HashWithPBKDF2

func HashWithPBKDF2(password string) (string, error)

HashWithPBKDF2 genera un hash usando PBKDF2-SHA256 con 600k iteraciones. Estándar NIST para entornos enterprise.

func HashWithScrypt

func HashWithScrypt(password string) (string, error)

HashWithScrypt genera un hash usando Scrypt con configuración estándar.

func NeedsUpgrade

func NeedsUpgrade(storedHash string) bool

NeedsUpgrade determina si un hash debe regenerarse con parámetros más seguros. Útil para migración gradual de hashes antiguos.

Ejemplo:

if crypto.NeedsUpgrade(hash) {
    nuevoHash, _ := crypto.HashPassword(password)
    // Guardar nuevoHash en BD
}

func RandomBytes

func RandomBytes(n int) ([]byte, error)

RandomBytes genera n bytes criptográficamente seguros usando crypto/rand. Esta es la función base sobre la que se construyen todas las demás.

Usa el generador de números aleatorios del sistema operativo, que está diseñado para ser impredecible y resistente a ataques.

Ejemplo de uso:

bytes, err := crypto.RandomBytes(32)
if err != nil {
    // Manejar error (fallo del sistema, muy raro)
}
// bytes contiene 32 bytes aleatorios seguros

func RandomHex

func RandomHex(n int) (string, error)

RandomHex genera una cadena hexadecimal de n bytes (2*n caracteres). Cada byte se representa con 2 caracteres hexadecimales (0-9, a-f).

Ideal para:

  • Refresh tokens
  • API keys
  • Identificadores de transacción
  • Tokens de verificación por email

Ejemplo de uso:

token := crypto.RandomHex(32)
// Resultado: "a1b2c3d4e5f6..." (64 caracteres hex)

func RandomString

func RandomString(n int) (string, error)

RandomString genera una cadena de n caracteres alfanuméricos URL-safe criptográficamente seguros. Usa el charset "A-Za-z0-9" (62 caracteres).

Ideal para:

  • Session IDs
  • Tokens CSRF
  • Identificadores únicos en URLs
  • Nonces criptográficos

Ejemplo de uso:

sessionID := crypto.RandomString(32)
// Resultado: "aB3xK9mP2qL5nR8wT1yU4zV6cF0hJ7d"

func SetDefaultHasher

func SetDefaultHasher(hasher Hasher)

SetDefaultHasher cambia el hasher global por defecto. Útil cuando quieres usar otro algoritmo como predeterminado.

Ejemplo:

crypto.SetDefaultHasher(crypto.NewBcryptHasher(crypto.HasherConfig{BcryptCost: 12}))

func SetEncryptionKey

func SetEncryptionKey(key []byte) error

SetEncryptionKey configura la clave global para cifrado/descifrado. DEBE llamarse antes de usar las funciones de cifrado en producción. La clave debe tener exactamente 32 bytes.

Ejemplo:

key, _ := crypto.GenerateEncryptionKey()
crypto.SetEncryptionKey(key)
// O desde variable de entorno:
// keyBytes, _ := base64.StdEncoding.DecodeString(os.Getenv("ENCRYPTION_KEY"))
// crypto.SetEncryptionKey(keyBytes)

func VerifyPassword

func VerifyPassword(password, storedHash string) (bool, error)

VerifyPassword verifica una contraseña contra un hash almacenado. Detecta automáticamente el algoritmo usado y lo verifica correctamente.

Ejemplo:

valid, err := crypto.VerifyPassword("mi-contraseña", "$argon2id$...")

Types

type AESEncrypter

type AESEncrypter struct {
	// contains filtered or unexported fields
}

AESEncrypter implementa la interfaz Encrypter usando AES-256-GCM. GCM (Galois/Counter Mode) proporciona tanto confidencialidad como autenticación, lo que significa que detecta cualquier manipulación de los datos cifrados.

Características de seguridad:

  • AES-256: Cifrado simétrico de 256 bits (estándar militar/gubernamental)
  • GCM Mode: Proporciona autenticación integrada (AEAD)
  • Nonce aleatorio: Cada cifrado usa un nonce único de 12 bytes
  • Sin padding: GCM no requiere padding, evitando ataques de padding oracle

func NewAESEncrypter

func NewAESEncrypter(key []byte) (*AESEncrypter, error)

NewAESEncrypter crea un nuevo cifrador AES-256-GCM con la clave proporcionada. La clave debe tener exactamente 32 bytes (256 bits).

Ejemplo de uso:

// Generar una clave segura
key, _ := crypto.GenerateEncryptionKey()

// Crear el cifrador
encrypter, err := crypto.NewAESEncrypter(key)
if err != nil {
    // Manejar error (clave inválida)
}

// Cifrar datos
encrypted, _ := encrypter.EncryptString("dato-sensible")

// Descifrar datos
decrypted, _ := encrypter.DecryptString(encrypted)

func (*AESEncrypter) Decrypt

func (e *AESEncrypter) Decrypt(ciphertext string) ([]byte, error)

Decrypt descifra los datos cifrados proporcionados. El proceso es: 1. Decodificar de base64 2. Extraer el nonce (primeros 12 bytes) 3. Extraer el ciphertext (resto) 4. Descifrar y verificar autenticación con GCM

Retorna un error si:

  • El formato es inválido
  • La clave es incorrecta
  • Los datos fueron manipulados (tag de autenticación no coincide)

Ejemplo de uso:

decrypted, err := encrypter.Decrypt(encrypted)
if err != nil {
    // Clave incorrecta o datos corruptos
}

func (*AESEncrypter) DecryptString

func (e *AESEncrypter) DecryptString(ciphertext string) (string, error)

DecryptString es una función de conveniencia para descifrar directamente a string. Internamente descifra y convierte el resultado de []byte a string.

Ejemplo de uso:

decrypted, err := encrypter.DecryptString(encrypted)
if err != nil {
    // Manejar error
}
fmt.Println(decrypted) // "API Secret Key"

func (*AESEncrypter) Encrypt

func (e *AESEncrypter) Encrypt(plaintext []byte) (string, error)

Encrypt cifra los datos proporcionados usando AES-256-GCM. El proceso es: 1. Generar un nonce aleatorio de 12 bytes 2. Cifrar los datos con GCM (incluye autenticación) 3. Concatenar nonce + ciphertext (necesario para descifrar) 4. Codificar en base64 para facilitar almacenamiento/transmisión

El resultado tiene el formato: base64(nonce + ciphertext + tag)

Ejemplo de uso:

plaintext := []byte("número de tarjeta: 4111-1111-1111-1111")
encrypted, err := encrypter.Encrypt(plaintext)
if err != nil {
    // Manejar error
}
// encrypted: "r4nd0mN0nc3...c1ph3rt3xt..."

func (*AESEncrypter) EncryptString

func (e *AESEncrypter) EncryptString(plaintext string) (string, error)

EncryptString es una función de conveniencia para cifrar strings directamente. Internamente convierte el string a []byte, cifra, y devuelve el resultado en base64.

Ejemplo de uso:

encrypted, err := encrypter.EncryptString("API Secret Key")
if err != nil {
    // Manejar error
}

type Algorithm

type Algorithm string

Algorithm representa el identificador del algoritmo de hashing de contraseñas.

const (
	// AlgorithmBcrypt es el estándar clásico ampliamente soportado.
	AlgorithmBcrypt Algorithm = "bcrypt"

	// AlgorithmArgon2id es el ganador del Password Hashing Competition (PHC).
	// Es el estándar recomendado actualmente por OWASP por su resistencia a GPUs/ASICs.
	AlgorithmArgon2id Algorithm = "argon2id"

	// AlgorithmScrypt es una alternativa con uso intensivo de memoria, útil para sistemas legacy.
	AlgorithmScrypt Algorithm = "scrypt"

	// AlgorithmPBKDF2 es el estándar NIST tradicional para entornos corporativos o legacy.
	AlgorithmPBKDF2 Algorithm = "pbkdf2"
)

func DetectAlgorithm

func DetectAlgorithm(hash string) (Algorithm, error)

DetectAlgorithm analiza la cabecera de la cadena de hash (formato PHC) y determina el algoritmo utilizado para su generación.

Formato general esperado: $identificador$parametros...

type Argon2Hasher

type Argon2Hasher struct {
	// contains filtered or unexported fields
}

Argon2Hasher implementa la interfaz Hasher usando el algoritmo argon2id. Argon2id es el ganador del Password Hashing Competition (2015) y es resistente a ataques GPU/ASIC gracias a su uso intensivo de memoria. Es la opción más segura actualmente disponible.

func NewArgon2Hasher

func NewArgon2Hasher(cfg HasherConfig) (*Argon2Hasher, error)

NewArgon2Hasher crea un nuevo hasher argon2id con la configuración especificada. Si no se proporcionan valores válidos, se usan parámetros seguros por defecto.

Parámetros recomendados (según RFC 9106):

  • Memoria: 64 MB mínimo, 256 MB para alta seguridad
  • Iteraciones: 3 mínimo
  • Paralelismo: Número de CPUs disponibles (1-8)
  • Longitud de clave: 32 bytes (256 bits)
  • Longitud de salt: 16 bytes mínimo

func (*Argon2Hasher) Hash

func (h *Argon2Hasher) Hash(password string) (string, error)

Hash genera un hash argon2id de la contraseña proporcionada. El resultado tiene el formato: $argon2id$v=19$m=65536,t=3,p=4$salt$hash

Este formato incluye todos los parámetros necesarios para verificar el hash en el futuro, incluso si los parámetros por defecto cambian.

func (*Argon2Hasher) NeedsUpgrade

func (h *Argon2Hasher) NeedsUpgrade(hash string) bool

NeedsUpgrade determina si un hash argon2id debe ser regenerado porque los parámetros configurados actualmente son más estrictos que los usados para generar el hash.

func (*Argon2Hasher) Verify

func (h *Argon2Hasher) Verify(password, hash string) (bool, error)

Verify compara una contraseña en texto plano con un hash argon2id. Extrae los parámetros del hash para garantizar que se usa la misma configuración que cuando se generó. Usa comparación de tiempo constante.

type BcryptHasher

type BcryptHasher struct {
	// contains filtered or unexported fields
}

BcryptHasher implementa la interfaz Hasher usando el algoritmo bcrypt. Bcrypt es ampliamente considerado el estándar de la industria para hashing de contraseñas debido a su adaptabilidad (costo ajustable) y resistencia a ataques de fuerza bruta.

func NewBcryptHasher

func NewBcryptHasher(cfg HasherConfig) (*BcryptHasher, error)

NewBcryptHasher crea un nuevo hasher bcrypt con la configuración especificada. Si no se proporciona un costo válido, se usa el valor predeterminado de 12.

El costo debe estar entre 4 y 31. Valores más altos son más seguros pero más lentos. Recomendaciones:

  • Desarrollo: 10
  • Producción estándar: 12
  • Alta seguridad: 14
  • Crítico: 15+

func (*BcryptHasher) Hash

func (h *BcryptHasher) Hash(password string) (string, error)

Hash genera un hash bcrypt de la contraseña proporcionada. El resultado incluye el salt y el hash en un solo string con el formato: $2a$12$salt...hash...

Bcrypt tiene un límite de 72 bytes: las contraseñas más largas se pre-hashean con SHA-256 (ver preprocessPassword) en lugar de truncarse, para no perder entropía de la parte final de la contraseña.

func (*BcryptHasher) NeedsUpgrade

func (h *BcryptHasher) NeedsUpgrade(hash string) bool

NeedsUpgrade determina si un hash bcrypt debe ser regenerado porque el costo configurado actualmente es mayor que el usado para generar el hash. Esto permite migrar gradualmente a costos más altos sin invalidar hashes existentes.

func (*BcryptHasher) Verify

func (h *BcryptHasher) Verify(password, hash string) (bool, error)

Verify compara una contraseña en texto plano con un hash bcrypt. Usa bcrypt.CompareHashAndPassword que internamente realiza una comparación de tiempo constante para prevenir ataques de timing.

type Encrypter

type Encrypter interface {
	// Encrypt cifra los datos proporcionados usando la clave configurada.
	// Los datos cifrados incluyen el nonce y el tag de autenticación.
	// El resultado está codificado en base64 para facilitar su almacenamiento.
	Encrypt(plaintext []byte) (string, error)

	// Decrypt descifra los datos cifrados proporcionados.
	// El input debe estar en base64 y contener el nonce, ciphertext y tag.
	// Retorna un error si la clave es incorrecta o los datos fueron manipulados.
	Decrypt(ciphertext string) ([]byte, error)

	// EncryptString es una conveniencia para cifrar strings directamente.
	EncryptString(plaintext string) (string, error)

	// DecryptString es una conveniencia para descifrar a string directamente.
	DecryptString(ciphertext string) (string, error)
}

Encrypter define el contrato para sistemas de cifrado simétrico. Esta abstracción permite cambiar el algoritmo de cifrado sin modificar el código que lo utiliza (principio Open/Closed).

type Hasher

type Hasher interface {
	// Hash genera un hash seguro de la contraseña proporcionada.
	Hash(password string) (string, error)

	// Verify compara una contraseña en texto plano con un hash almacenado.
	// Devuelve true si coinciden, false en caso contrario.
	// Nota: Debe implementarse usando comparación en tiempo constante (subtle.ConstantTimeCompare)
	// para prevenir ataques de temporización (timing attacks).
	Verify(password, hash string) (bool, error)

	// NeedsUpgrade determina si un hash existente debe ser regenerado
	// (ej. si el algoritmo por defecto cambió o si los parámetros de seguridad han aumentado).
	NeedsUpgrade(hash string) bool
}

Hasher define el contrato que deben cumplir todos los proveedores de hashing de contraseñas. Esta abstracción permite cambiar el algoritmo subyacente sin modificar el código consumidor (principio Open/Closed).

func NewHasher

func NewHasher(cfg HasherConfig) (Hasher, error)

NewHasher crea y devuelve un proveedor que implementa la interfaz Hasher. Si los parámetros numéricos de la configuración son 0, la implementación concreta asignará defaults seguros automáticamente.

type HasherConfig

type HasherConfig struct {
	// Algorithm especifica qué algoritmo se instanciará.
	Algorithm Algorithm

	// --- Parámetros específicos de Bcrypt ---
	BcryptCost int

	// --- Parámetros específicos de Argon2id ---
	Argon2Memory      uint32 // Memoria en KB (ej. 65536 = 64MB)
	Argon2Iterations  uint32 // Número de pasadas
	Argon2Parallelism uint8  // Goroutines en paralelo
	Argon2KeyLength   uint32 // Longitud de la clave generada
	Argon2SaltLength  uint32 // Longitud del salt

	// --- Parámetros específicos de Scrypt ---
	ScryptN       int
	ScryptR       int
	ScryptP       int
	ScryptKeyLen  int
	ScryptSaltLen int

	// --- Parámetros específicos de PBKDF2 ---
	PBKDF2Iterations int
	PBKDF2KeyLen     int
	PBKDF2SaltLen    int
}

HasherConfig contiene los parámetros necesarios para instanciar cualquier proveedor Hasher.

type PBKDF2Hasher

type PBKDF2Hasher struct {
	// contains filtered or unexported fields
}

PBKDF2Hasher implementa la interfaz Hasher usando el algoritmo PBKDF2 (Password-Based Key Derivation Function 2) con SHA-256. PBKDF2 es el estándar recomendado por NIST (NIST SP 800-132) y es ampliamante usado en aplicaciones enterprise y sistemas legacy.

Aunque no es tan resistente a ataques GPU como argon2 o scrypt, sigue siendo una opción segura y ampliamente aceptada cuando se usa con suficientes iteraciones.

func NewPBKDF2Hasher

func NewPBKDF2Hasher(cfg HasherConfig) (*PBKDF2Hasher, error)

NewPBKDF2Hasher crea un nuevo hasher PBKDF2 con la configuración especificada. Si no se proporcionan valores válidos, se usan parámetros seguros por defecto.

Parámetros recomendados (según NIST SP 800-132):

  • Iteraciones: 600,000 mínimo (recomendación OWASP 2023 para SHA-256)
  • keyLen: 32 bytes (256 bits)
  • saltLen: 16 bytes mínimo

Nota: OWASP recomienda aumentar las iteraciones con el tiempo a medida que el hardware se vuelve más potente.

func (*PBKDF2Hasher) Hash

func (h *PBKDF2Hasher) Hash(password string) (string, error)

Hash genera un hash PBKDF2-SHA256 de la contraseña proporcionada. El resultado tiene el formato: $pbkdf2-sha256$i=600000$salt$hash

Este formato incluye todos los parámetros necesarios para verificar el hash en el futuro, permitiendo migración transparente entre diferentes configuraciones.

func (*PBKDF2Hasher) NeedsUpgrade

func (h *PBKDF2Hasher) NeedsUpgrade(hash string) bool

NeedsUpgrade determina si un hash PBKDF2 debe ser regenerado porque el número de iteraciones configurado actualmente es mayor que el usado para generar el hash.

func (*PBKDF2Hasher) Verify

func (h *PBKDF2Hasher) Verify(password, hash string) (bool, error)

Verify compara una contraseña en texto plano con un hash PBKDF2. Extrae los parámetros del hash para garantizar que se usa la misma configuración que cuando se generó. Usa comparación de tiempo constante.

type ScryptHasher

type ScryptHasher struct {
	// contains filtered or unexported fields
}

ScryptHasher implementa la interfaz Hasher usando el algoritmo scrypt. Scrypt fue diseñado por Colin Percival como una función de derivación de claves con uso intensivo de memoria, lo que la hace resistente a ataques con hardware especializado (GPUs, ASICs). Es una alternativa sólida a bcrypt y argon2.

func NewScryptHasher

func NewScryptHasher(cfg HasherConfig) (*ScryptHasher, error)

NewScryptHasher crea un nuevo hasher scrypt con la configuración especificada. Si no se proporcionan valores válidos, se usan parámetros seguros por defecto.

Parámetros recomendados (según Colin Percival):

  • N (costo CPU/memoria): 16384 mínimo, 2^14-2^20 recomendado
  • r (tamaño de bloque): 8 (estándar)
  • p (paralelismo): 1 (estándar para contraseñas)
  • keyLen: 32 bytes (256 bits)
  • saltLen: 16 bytes mínimo

Nota: N debe ser potencia de 2 y mayor que 1.

func (*ScryptHasher) Hash

func (h *ScryptHasher) Hash(password string) (string, error)

Hash genera un hash scrypt de la contraseña proporcionada. El resultado tiene el formato: $scrypt$ln=14,r=8,p=1$salt$hash

Donde ln es el log2 de N (para facilitar la lectura). Este formato incluye todos los parámetros necesarios para verificar el hash en el futuro, permitiendo migración transparente.

func (*ScryptHasher) NeedsUpgrade

func (h *ScryptHasher) NeedsUpgrade(hash string) bool

NeedsUpgrade determina si un hash scrypt debe ser regenerado porque los parámetros configurados actualmente son más estrictos que los usados para generar el hash.

func (*ScryptHasher) Verify

func (h *ScryptHasher) Verify(password, hash string) (bool, error)

Verify compara una contraseña en texto plano con un hash scrypt. Extrae los parámetros del hash para garantizar que se usa la misma configuración que cuando se generó. Usa comparación de tiempo constante.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL