Cryptographie en Go (Golang) : chiffrement et hachage de données
Le langage Go (Golang) offre une bibliothèque standard puissante et élégante pour les opérations cryptographiques. Contrairement à de nombreux autres langages où l'installation de paquets tiers est nécessaire, Go intègre la prise en charge du chiffrement symétrique et asymétrique, ainsi que des algorithmes de hachage modernes, directement "prêts à l'emploi". Dans cet article, nous allons détailler comment utiliser la cryptographie en Go pour protéger les données sur le portail éducatif pythonlib.ru.
Principaux paquets de cryptographie en Go
Toute la cryptographie en Go est concentrée dans le paquet crypto et ses sous-paquets. Voici les principaux :
crypto/aes— implémentation de l'Advanced Encryption Standard (AES).crypto/cipher— interfaces pour les modes de chiffrement (CBC, GCM, CTR).crypto/rsa— chiffrement asymétrique RSA.crypto/sha256,crypto/sha512— fonctions de hachage de la famille SHA-2.golang.org/x/crypto/bcrypt— hachage adaptatif de mots de passe (paquet supplémentaire).crypto/rand— générateur de nombres aléatoires cryptographiquement sûr.
Chiffrement symétrique AES en Go
Le chiffrement symétrique utilise la même clé pour chiffrer et déchiffrer. Voici un exemple avec AES-256 en mode GCM (Galois/Counter Mode), qui assure l'authentification des données.
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 }
// Créer le mode GCM (Galois/Counter Mode) gcm, err := cipher.NewGCM(block) if err != nil { return nil, err }
// Générer un nonce aléatoire (nombre à usage unique) nonce := make([]byte, gcm.NonceSize()) if _, err := io.ReadFull(rand.Reader, nonce); err != nil { return nil, err }
// Seal ajoute le nonce au début du texte chiffré 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 octets pour AES-128 plaintext := []byte("Données secrètes pour PythonLib")
encrypted, _ := encryptAES(plaintext, key) fmt.Println("Chiffré (hex):", hex.EncodeToString(encrypted))
decrypted, _ := decryptAES(encrypted, key) fmt.Println("Déchiffré:", string(decrypted))}Remarque : la clé doit avoir une longueur de 16, 24 ou 32 octets respectivement pour AES-128, AES-192 ou AES-256. Le nonce (IV) est généré aléatoirement et est stocké avec le texte chiffré.
Chiffrement asymétrique RSA en Go
RSA utilise une paire de clés : une clé publique pour le chiffrement et une clé privée pour le déchiffrement. C'est idéal pour un échange sécurisé de données entre le serveur et le client.
package main
import ( "crypto/rand" "crypto/rsa" "crypto/sha256" "fmt")
func generateKeyPair(bits int) (*rsa.PrivateKey, error) {