Cryptographie en Java : chiffrement et hachage – guide pratique

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

Cryptographie en Java : chiffrement et hachage – guide complet



La cryptographie est le fondement de la sécurité des applications modernes. Java intègre une infrastructure puissante et flexible pour le chiffrement et le hachage — Java Cryptography Architecture (JCA) et Java Cryptography Extension (JCE). Ces bibliothèques permettent de mettre en œuvre aussi bien le chiffrement symétrique (AES) qu'asymétrique (RSA), ainsi que le hachage cryptographique (SHA-256). Dans cet article, nous aborderons les concepts clés et écrirons des exemples fonctionnels en Java pur (sans dépendances externes).



Concepts de base et architecture JCA/JCE

JCA fournit un cadre pour les opérations cryptographiques. L'idée clé réside dans les fournisseurs (providers) qui implémentent des algorithmes spécifiques. Par défaut, le JDK inclut le fournisseur SUN (pour les hachages) et SunJCE (pour le chiffrement). Les classes principales se trouvent dans les paquets javax.crypto et java.security.

  • Cipher — la classe principale pour le chiffrement et le déchiffrement.
  • KeyGenerator — génération de clés symétriques.
  • KeyPairGenerator — génération de paires de clés pour le chiffrement asymétrique.
  • MessageDigest — calcul d'empreintes de hachage.
  • SecretKeySpec — représentation d'une clé symétrique à partir d'un tableau d'octets.


Chiffrement symétrique : AES

AES (Advanced Encryption Standard) est l'algorithme symétrique le plus populaire. Il utilise la même clé pour le chiffrement et le déchiffrement. Le mode recommandé est GCM (chiffrement authentifié) ou CBC avec PKCS5Padding. Voici un exemple de chiffrement d'une chaîne avec AES-256/GCM.



import javax.crypto.Cipher;import javax.crypto.KeyGenerator;import javax.crypto.SecretKey;import javax.crypto.spec.GCMParameterSpec;import java.security.SecureRandom;import java.util.Base64;

public class AESGCMExample { private static final int AES_KEY_SIZE = 256; private static final int GCM_IV_LENGTH = 12; private static final int GCM_TAG_LENGTH = 128;

public static SecretKey generateKey() throws Exception { KeyGenerator keyGen = KeyGenerator.getInstance("AES"); keyGen.init(AES_KEY_SIZE, SecureRandom.getInstanceStrong()); return keyGen.generateKey(); }

public static String encrypt(String plaintext, SecretKey key) throws Exception { byte[] iv = new byte[GCM_IV_LENGTH]; SecureRandom.getInstanceStrong().nextBytes(iv); Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding"); GCMParameterSpec spec = new GCMParameterSpec(GCM_TAG_LENGTH, iv); cipher.init(Cipher.ENCRYPT_MODE, key, spec); byte[] cipherText = cipher.doFinal(plaintext.getBytes()); byte[] encrypted = new byte[iv.length + cipherText.length]; System.arraycopy(iv, 0, encrypted, 0, iv.length); System.arraycopy(cipherText, 0, encrypted, iv.length, cipherText.length); return Base64.getEncoder().encodeToString(encrypted); }

public static String decrypt(String encryptedData, SecretKey key) throws Exception { byte[] decoded = Base64.getDecoder().decode(encryptedData); byte[] iv = new byte[GCM_IV_LENGTH]; System.arraycopy(decoded, 0, iv, 0, iv.length); byte[] cipherText = new byte[decoded.length - iv.length]; System.arraycopy(decoded, iv.length, cipherText, 0, cipherText.length); Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding"); GCMParameterSpec spec = new GCMParameterSpec(GCM_TAG_LENGTH, iv); cipher.init(Cipher.DECRYPT_MODE, key, spec); return new String(cipher.doFinal(cipherText)); }

public static void main(String[] args) throws Exception { SecretKey key = generateKey()

Recommendations