Szyfrowanie symetryczne AES
Proszę szyfrować i deszyfrować wrażliwe dane za pomocą AES/CBC/PKCS5Padding, korzystając z interfejsu API javax.crypto języka Java.
Szyfrowanie symetryczne AES to bezpłatna lekcja Java Academy na CoddyKit. To lekcja 2 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Java Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Java Academy zawiera 4 lekcji w sumie.
Szyfrowanie symetryczne a asymetryczne
Szyfrowanie symetryczne korzysta z tego samego klucza do szyfrowania i deszyfrowania (jest szybkie i nadaje się do dużych ilości danych). Szyfrowanie asymetryczne korzysta z pary kluczy publicznego i prywatnego (jest wolniejsze i służy do wymiany kluczy oraz tworzenia podpisów). AES to standardowy szyfr symetryczny.
Tryby AES: CBC a GCM
AES ma kilka trybów. AES/CBC/PKCS5Padding jest popularny, ale nie zapewnia uwierzytelniania. AES/GCM/NoPadding zapewnia zarówno szyfrowanie, jak i uwierzytelnianie (AEAD) — zdecydowanie zaleca się go w nowym kodzie.
Generowanie klucza AES
Do bezpiecznego wygenerowania 256-bitowego klucza AES należy użyć KeyGenerator.
KeyGenerator kg = KeyGenerator.getInstance("AES");
kg.init(256); // 256-bit key
SecretKey key = kg.generateKey();
// Persist the key:
String b64Key = Base64.getEncoder().encodeToString(key.getEncoded());
// Restore the key:
byte[] decoded = Base64.getDecoder().decode(b64Key);
SecretKey restored = new SecretKeySpec(decoded, "AES");Szyfrowanie AES/GCM
Tryb GCM wymaga unikalnego 12-bajtowego wektora inicjalizacyjnego (IV) dla każdego szyfrowania. Dla każdej operacji szyfrowania należy generować nowy, losowy IV — nigdy nie wolno ponownie używać IV z tym samym kluczem.
byte[] iv = new byte[12]; // 96-bit IV for GCM
new SecureRandom().nextBytes(iv);
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
GCMParameterSpec spec = new GCMParameterSpec(128, iv); // 128-bit auth tag
cipher.init(Cipher.ENCRYPT_MODE, key, spec);
byte[] ciphertext = cipher.doFinal(plaintext.getBytes(StandardCharsets.UTF_8));
// Transmit/store: IV + ciphertext (IV is not secret)Deszyfrowanie AES/GCM
Należy wyodrębnić IV z przechowywanych danych, odtworzyć specyfikację i wykonać deszyfrowanie. GCM automatycznie weryfikuje autentyczność — zmodyfikowane dane powodują zgłoszenie AEADBadTagException.
// Assume stored = iv + ciphertext:
byte[] iv = Arrays.copyOfRange(stored, 0, 12);
byte[] ciphertext = Arrays.copyOfRange(stored, 12, stored.length);
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
cipher.init(Cipher.DECRYPT_MODE, key, new GCMParameterSpec(128, iv));
byte[] plaintext = cipher.doFinal(ciphertext); // throws if tamperedPrzechowywanie IV razem z szyfrogramem
IV nie jest tajny — można przechowywać go przed szyfrogramem lub obok niego. Odbiorca potrzebuje IV do odszyfrowania danych. Klucz musi pozostać tajny.
byte[] encryptedData = new byte[iv.length + ciphertext.length];
System.arraycopy(iv, 0, encryptedData, 0, iv.length);
System.arraycopy(ciphertext, 0, encryptedData, iv.length, ciphertext.length);
String b64 = Base64.getEncoder().encodeToString(encryptedData);Wyprowadzanie klucza z hasła (PBKDF2)
Nigdy nie należy używać hasła bezpośrednio jako klucza AES — jego entropia jest zbyt mała. Klucz należy wyprowadzić za pomocą PBKDF2, używając losowej soli i dużej liczby iteracji.
PBEKeySpec spec = new PBEKeySpec(password.toCharArray(), salt, 310_000, 256);
SecretKeyFactory skf = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
byte[] keyBytes = skf.generateSecret(spec).getEncoded();
SecretKey key = new SecretKeySpec(keyBytes, "AES");Korzystanie z dostawcy zabezpieczeń Java
Domyślny dostawca JDK obsługuje AES. W przypadku dodatkowych algorytmów lub zgodności z FIPS należy użyć dostawcy Bouncy Castle.
// With Bouncy Castle:
Security.addProvider(new BouncyCastleProvider());
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding", "BC");Wzorzec szyfrowania kopertowego
Dane należy zaszyfrować za pomocą losowo wygenerowanego klucza szyfrowania danych (DEK). Następnie DEK należy zaszyfrować kluczem szyfrowania kluczy (KEK) przechowywanym w KMS (AWS KMS, HashiCorp Vault). Ogranicza to ekspozycję kluczy.
AES w aplikacjach Spring
TextEncryptor z Spring Security lub moduł Spring Security Crypto zapewniają wysokopoziomowe szyfrowanie AES bez konieczności ręcznego zarządzania Cipher/IV.
TextEncryptor encryptor = Encryptors.text(password, salt);
String encrypted = encryptor.encrypt("sensitive data");
String decrypted = encryptor.decrypt(encrypted);Typowe pułapki
Nigdy nie należy: ponownie używać IV z tym samym kluczem, używać trybu ECB (zachowuje wzorce), używać hasła bezpośrednio jako klucza ani ignorować tagu uwierzytelniania. W nowym kodzie należy zawsze używać GCM.
Szybkie sprawdzenie
Co zapewnia AES/GCM, czego nie zapewnia AES/CBC?
Podsumowanie
Do uwierzytelnionego szyfrowania należy używać AES/GCM/NoPadding. Dla każdego szyfrowania należy generować nowy, losowy 12-bajtowy IV. IV należy umieszczać przed szyfrogramem. Klucze z haseł należy wyprowadzać za pomocą PBKDF2. Nigdy nie wolno ponownie używać IV z tym samym kluczem.
Często zadawane pytania
Czy lekcja „Szyfrowanie symetryczne AES” jest bezpłatna?
Tak — pełny tekst „Szyfrowanie symetryczne AES” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Java Academy, przejdź na CoddyKit PRO. Kurs Java Academy zawiera 4 lekcji w sumie.
Co nauczysz się w „Szyfrowanie symetryczne AES”?
Proszę szyfrować i deszyfrować wrażliwe dane za pomocą AES/CBC/PKCS5Padding, korzystając z interfejsu API javax.crypto języka Java. Ćwiczysz Java Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.
Czy potrzebuję doświadczenia, aby zacząć Java Academy?
Nie wymagamy żadnego doświadczenia. Java Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 2 z 4.
Ile czasu zajmuje lekcja „Szyfrowanie symetryczne AES”?
Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.
Czy mogę pisać i uruchamiać kod w tej lekcji Java Academy?
Tak. Każda lekcja Java Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.
Wszystkie lekcje w tym kursie
- Haszowanie kryptograficzne za pomocą MessageDigest
- Szyfrowanie symetryczne AES
- HMAC-SHA256 na potrzeby integralności wiadomości
- JWT: struktura, tworzenie i weryfikacja