Криптография в Java: шифрование и хеширование данных

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Криптография в Java: шифрование и хеширование

В современном мире информационной безопасности криптография играет ключевую роль. Java предоставляет мощные встроенные средства для реализации криптографических операций через Java Cryptography Architecture (JCA) и Java Cryptography Extension (JCE). В этой статье мы подробно разберем основные механизмы: симметричное шифрование, асимметричное шифрование и хеширование, а также приведем практические примеры кода.

Основные понятия криптографии

Прежде чем перейти к коду, важно понимать разницу между основными криптографическими примитивами:

  • Симметричное шифрование — использует один и тот же ключ для шифрования и расшифровки данных. Быстрое, но требует безопасной передачи ключа.
  • Асимметричное шифрование — использует пару ключей: открытый (для шифрования) и закрытый (для расшифровки). Медленнее, но решает проблему обмена ключами.
  • Хеширование — необратимое преобразование данных в строку фиксированной длины. Используется для проверки целостности и хранения паролей.

Симметричное шифрование AES в Java

AES (Advanced Encryption Standard) — самый популярный симметричный алгоритм. В Java работа с ним осуществляется через класс Cipher. Рассмотрим пример шифрования и расшифровки строки:

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;

public class AesExample {
    public static void main(String[] args) throws Exception {
        // Генерация ключа AES-128
        KeyGenerator keyGen = KeyGenerator.getInstance("AES");
        keyGen.init(128);
        SecretKey secretKey = keyGen.generateKey();
        
        // Исходное сообщение
        String originalMessage = "Привет, криптография!";
        System.out.println("Исходное сообщение: " + originalMessage);
        
        // Шифрование
        Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, secretKey);
        byte[] encryptedBytes = cipher.doFinal(originalMessage.getBytes("UTF-8"));
        String encryptedMessage = Base64.getEncoder().encodeToString(encryptedBytes);
        System.out.println("Зашифрованное сообщение: " + encryptedMessage);
        
        // Расшифровка
        cipher.init(Cipher.DECRYPT_MODE, secretKey);
        byte[] decryptedBytes = cipher.doFinal(Base64.getDecoder().decode(encryptedMessage));
        String decryptedMessage = new String(decryptedBytes, "UTF-8");
        System.out.println("Расшифрованное сообщение: " + decryptedMessage);
    }
}

В примере используется режим ECB (Electronic Codebook) с дополнением PKCS5Padding. Для продакшена рекомендуется использовать более безопасные режимы, такие как CBC или GCM.

Асимметричное шифрование RSA

RSA — классический асимметричный алгоритм. В Java для работы с ним используются классы KeyPairGenerator и Cipher. Важно помнить: RSA может шифровать данные только до размера ключа (обычно 2048 бит). Для больших объёмов данных RSA комбинируют с симметричным шифрованием (гибридная схема).

import javax.crypto.Cipher;
import java.security.*;
import java.util.Base64;

public class RsaExample {
    public static void main(String[] args) throws Exception {
        // Генерация пары ключей RSA-2048
        KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
        keyGen.initialize(2048);
        KeyPair keyPair = keyGen.generateKeyPair();
        PublicKey publicKey = keyPair.getPublic();
        PrivateKey privateKey = keyPair.getPrivate();
        
        String secretMessage = "Секретные данные";
        System.out.println("Исходное сообщение: " + secretMessage);
        
        // Шифрование открытым ключом
        Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding");
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        byte[] encryptedBytes = cipher.doFinal(secretMessage.getBytes("UTF-8"));
        String encryptedMessage = Base64.getEncoder().encodeToString(encryptedBytes);
        System.out.println("Зашифрованное сообщение: " + encryptedMessage);
        
        // Расшифровка закрытым ключом
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        byte[] decryptedBytes = cipher.doFinal(Base64.getDecoder().decode(encryptedMessage));
        String decryptedMessage = new String(decryptedBytes, "UTF-8");
        System.out.println("Расшифрованное сообщение: " + decryptedMessage);
    }
}

Обратите внимание: мы используем OAEP (Optimal Asymmetric Encryption Padding) — это рекомендованный способ дополнения для RSA, обеспечивающий дополнительную защиту.

Хеширование с SHA-256

Хеширование — неотъемлемая часть криптографии, особенно при хранении паролей. В Java для хеширования используется класс

Рекомендаций