Criptografía en Go (Golang): cifrado y hash de datos
El lenguaje Go (Golang) proporciona una biblioteca estándar potente y elegante para operaciones criptográficas. A diferencia de muchos otros lenguajes, donde se requiere instalar paquetes de terceros, Go incluye soporte para cifrado simétrico y asimétrico, así como algoritmos de hash modernos directamente "de fábrica". En este artículo, analizaremos en detalle cómo usar la criptografía en Go para proteger datos en el portal educativo pythonlib.ru.
Paquetes principales de criptografía en Go
Toda la criptografía en Go se concentra en el paquete crypto y sus subpaquetes. Estos son los clave:
crypto/aes— implementación del Advanced Encryption Standard (AES).crypto/cipher— interfaces para modos de cifrado (CBC, GCM, CTR).crypto/rsa— cifrado asimétrico RSA.crypto/sha256,crypto/sha512— funciones hash de la familia SHA-2.golang.org/x/crypto/bcrypt— hash adaptativo de contraseñas (paquete adicional).crypto/rand— generador de números aleatorios criptográficamente seguro.
Cifrado simétrico AES en Go
El cifrado simétrico utiliza la misma clave para cifrar y descifrar. Veamos un ejemplo con AES-256 en modo GCM (Galois/Counter Mode), que proporciona autenticación de datos.
package main
import ( "crypto/aes" "crypto/cipher" "crypto/rand" "encoding/hex" "fmt" "io")
func encryptAES(plaintext []byte, key []byte) ([]byte, error) { block, err := aes.NewCipher(key) if err != nil { return nil, err }
// Creamos GCM (Galois/Counter Mode) gcm, err := cipher.NewGCM(block) if err != nil { return nil, err }
// Generamos un nonce aleatorio (número usado una vez) nonce := make([]byte, gcm.NonceSize()) if _, err := io.ReadFull(rand.Reader, nonce); err != nil { return nil, err }
// Seal añade el nonce al inicio del texto cifrado ciphertext := gcm.Seal(nonce, nonce, plaintext, nil) return ciphertext, nil}
func decryptAES(ciphertext []byte, key []byte) ([]byte, error) { block, err := aes.NewCipher(key) if err != nil { return nil, err }
gcm, err := cipher.NewGCM(block) if err != nil { return nil, err }
nonceSize := gcm.NonceSize() if len(ciphertext) < nonceSize { return nil, fmt.Errorf("ciphertext too short") }
nonce, ciphertext := ciphertext[:nonceSize], ciphertext[nonceSize:] plaintext, err := gcm.Open(nil, nonce, ciphertext, nil) if err != nil { return nil, err } return plaintext, nil}
func main() { key := []byte("examplekey123456") // 16 bytes para AES-128 plaintext := []byte("Datos secretos para PythonLib")
encrypted, _ := encryptAES(plaintext, key) fmt.Println("Cifrado (hex):", hex.EncodeToString(encrypted))
decrypted, _ := decryptAES(encrypted, key) fmt.Println("Descifrado:", string(decrypted))}Tenga en cuenta: la clave debe tener una longitud de 16, 24 o 32 bytes para AES-128, AES-192 o AES-256 respectivamente. El nonce (IV) se genera aleatoriamente y se almacena junto con el texto cifrado.
Cifrado asimétrico RSA en Go
RSA utiliza un par de claves: una pública (public) para cifrar y una privada (private) para descifrar. Esto es ideal para el intercambio seguro de datos entre el servidor y el cliente.
package main
import ( "crypto/rand" "crypto/rsa" "crypto/sha256" "fmt")
func generateKeyPair(bits int) (*rsa.PrivateKey, error) { También en la biblioteca
Cliente OAuth para Node.js: implementación de autorización a través de Google y GitHub
Internacionalización (i18n) en Java: guía completa con ejemplos
Bean Validation (Jakarta Validation) — Validación de datos en Java
Trabajo con CSV en Rust: bibliotecas csv, serde y procesamiento eficiente de datos
GraphQL en Go: Guía completa sobre la biblioteca gqlgen