Java for Beginner
677 subscribers
546 photos
155 videos
12 files
838 links
Канал от новичков для новичков!
Изучайте Java вместе с нами!
Здесь мы обмениваемся опытом и постоянно изучаем что-то новое!

Наш YouTube канал - https://www.youtube.com/@Java_Beginner-Dev

Наш канал на RUTube - https://rutube.ru/channel/37896292/
Download Telegram
Java Crypto API

Классы Cipher и KeyGenerator

1. Класс Cipher (шифрование и дешифрование)
Класс Cipher является основным инструментом для шифрования и дешифрования данных в Java. Он поддерживает различные алгоритмы шифрования, такие как AES, DES, RSA и другие.

Как работает Cipher под капотом?
Cipher использует провайдеры безопасности (Security Providers), которые реализуют конкретные алгоритмы шифрования. Например, провайдер SunJCE предоставляет реализации AES, DES и других алгоритмов.
Внутри Cipher использует режимы шифрования (например, ECB, CBC, GCM) и дополнительные параметры (например, векторы инициализации).

Класс работает в трех режимах:
Шифрование (ENCRYPT_MODE).
Дешифрование (DECRYPT_MODE).
Обертывание ключей (WRAP_MODE).


Основные методы Cipher

getInstance(String transformation): Создает экземпляр Cipher для указанного алгоритма и режима (например, "AES/CBC/PKCS5Padding").
init(int opmode, Key key): Инициализирует Cipher для шифрования или дешифрования с использованием ключа.
doFinal(byte[] input): Выполняет шифрование или дешифрование данных.
update(byte[] input): Обновляет данные для пошаговой обработки (полезно для больших данных).


Пример использования Cipher
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import java.util.Base64;

public class CipherExample {
public static void main(String[] args) throws Exception {
// Генерация ключа
KeyGenerator keyGen = KeyGenerator.getInstance("AES");
keyGen.init(128); // 128-битный ключ
SecretKey secretKey = keyGen.generateKey();

// Создание Cipher для AES
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, secretKey);

// Шифрование данных
String originalText = "Hello, Java Crypto!";
byte[] encryptedBytes = cipher.doFinal(originalText.getBytes());
System.out.println("Encrypted: " + Base64.getEncoder().encodeToString(encryptedBytes));

// Дешифрование данных
cipher.init(Cipher.DECRYPT_MODE, secretKey);
byte[] decryptedBytes = cipher.doFinal(encryptedBytes);
System.out.println("Decrypted: " + new String(decryptedBytes));
}
}


Плюсы и минусы Cipher

Плюсы:
Поддержка множества алгоритмов и режимов шифрования.
Гибкость в использовании (пошаговая обработка, обертывание ключей).


Минусы
Требует правильной настройки параметров (например, режима и вектора инициализации).
Может быть сложным для новичков.


2. Класс KeyGenerator (генерация симметричных ключей)
Класс KeyGenerator используется для генерации симметричных ключей, которые применяются в алгоритмах шифрования, таких как AES, DES и других.

Как работает KeyGenerator под капотом?
KeyGenerator использует криптографически безопасные генераторы случайных чисел (CSPRNG) для создания ключей.
Размер ключа зависит от алгоритма (например, 128, 192 или 256 бит для AES).

Основные методы KeyGenerator

getInstance(String algorithm): Создает экземпляр KeyGenerator для указанного алгоритма (например, "AES").
init(int keysize): Устанавливает размер ключа.
generateKey(): Генерирует симметричный ключ.


Пример использования KeyGenerator
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import java.util.Base64;

public class KeyGeneratorExample {
public static void main(String[] args) throws Exception {
// Создание KeyGenerator для AES
KeyGenerator keyGen = KeyGenerator.getInstance("AES");
keyGen.init(256); // 256-битный ключ

// Генерация ключа
SecretKey secretKey = keyGen.generateKey();
System.out.println("Generated Key: " + Base64.getEncoder().encodeToString(secretKey.getEncoded()));
}
}


Плюсы и минусы KeyGenerator

Плюсы:
Простота генерации ключей.
Поддержка различных алгоритмов.


Минусы:
Ключи должны храниться безопасно (например, в KeyStore).
Не подходит для асимметричных ключей (для этого используется KeyPairGenerator)


#Java #Training #Medium #Java_Crypto_API #Cipher #KeyGenerator
Java Crypto API

Классы SecretKey и IvParameterSpec

1. Класс SecretKey (работа с симметричными ключами)
Класс SecretKey представляет собой интерфейс, который используется для работы с симметричными ключами. Он является частью Java Cryptography Architecture (JCA) и реализуется классами, предоставляемыми провайдерами безопасности (например, SecretKeySpec).

Как работает SecretKey под капотом?
SecretKey — это интерфейс, который расширяет интерфейс Key. Он предоставляет методы для получения закодированного представления ключа и информации о его алгоритме.
Реализация SecretKey (например, SecretKeySpec) хранит ключ в виде массива байт и предоставляет методы для доступа к этим данным.


Основные методы SecretKey

getEncoded(): Возвращает закодированное представление ключа в виде массива байт.
getAlgorithm(): Возвращает имя алгоритма, для которого предназначен ключ (например, "AES").
getFormat(): Возвращает формат, в котором закодирован ключ (например, "RAW").


Пример использования SecretKey
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import java.util.Base64;

public class SecretKeyExample {
public static void main(String[] args) throws Exception {
// Генерация ключа с помощью KeyGenerator
KeyGenerator keyGen = KeyGenerator.getInstance("AES");
keyGen.init(128); // 128-битный ключ
SecretKey secretKey = keyGen.generateKey();

// Получение закодированного ключа
byte[] keyBytes = secretKey.getEncoded();
System.out.println("Key (Base64): " + Base64.getEncoder().encodeToString(keyBytes));

// Получение информации о ключе
System.out.println("Algorithm: " + secretKey.getAlgorithm());
System.out.println("Format: " + secretKey.getFormat());
}
}


Плюсы и минусы SecretKey

Плюсы:
Универсальный интерфейс для работы с симметричными ключами.
Поддерживает различные алгоритмы шифрования.


Минусы:
Ключи должны храниться безопасно (например, в KeyStore).
Не подходит для асимметричных ключей.


2. Класс IvParameterSpec (векторы инициализации)
Класс IvParameterSpec используется для работы с векторами инициализации (IV), которые необходимы для некоторых режимов шифрования, таких как CBC (Cipher Block Chaining) или GCM (Galois/Counter Mode).

Как работает IvParameterSpec под капотом?
Вектор инициализации (IV) — это случайное значение, которое используется для обеспечения уникальности шифрования даже при использовании одного и того же ключа.
IvParameterSpec — это простая обертка вокруг массива байт, представляющего IV.


#Java #Training #Medium #Java_Crypto_API #SecretKey #IvParameterSpec
Основные методы IvParameterSpec

IvParameterSpec(byte[] iv): Создает объект IvParameterSpec с указанным вектором инициализации.
getIV(): Возвращает вектор инициализации в виде массива байт.


Пример использования IvParameterSpec

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

public class IvParameterSpecExample {
public static void main(String[] args) throws Exception {
// Генерация ключа
KeyGenerator keyGen = KeyGenerator.getInstance("AES");
keyGen.init(128); // 128-битный ключ
SecretKey secretKey = keyGen.generateKey();

// Генерация вектора инициализации
byte[] iv = new byte[16]; // 16 байт для AES
SecureRandom random = new SecureRandom();
random.nextBytes(iv);
IvParameterSpec ivSpec = new IvParameterSpec(iv);

// Шифрование с использованием IV
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivSpec);

String originalText = "Hello, Java Crypto!";
byte[] encryptedBytes = cipher.doFinal(originalText.getBytes());
System.out.println("Encrypted: " + Base64.getEncoder().encodeToString(encryptedBytes));

// Дешифрование с использованием IV
cipher.init(Cipher.DECRYPT_MODE, secretKey, ivSpec);
byte[] decryptedBytes = cipher.doFinal(encryptedBytes);
System.out.println("Decrypted: " + new String(decryptedBytes));
}
}


Плюсы и минусы IvParameterSpec

Плюсы:
Обеспечивает уникальность шифрования даже при использовании одного ключа.
Простота использования.


Минусы:
IV должен быть случайным и уникальным для каждого шифрования.
IV должен передаваться вместе с зашифрованными данными.


#Java #Training #Medium #Java_Crypto_API #SecretKey #IvParameterSpec
Java Crypto API

Классы KeyPairGenerator и KeyPair

Класс KeyPairGenerator (генерация асимметричных ключей)

Класс KeyPairGenerator используется для генерации пары асимметричных ключей: открытого (public key) и закрытого (private key). Эти ключи применяются в асимметричных алгоритмах, таких как RSA, DSA и ECDSA.

Как работает KeyPairGenerator под капотом?
KeyPairGenerator использует криптографически безопасные генераторы случайных чисел (CSPRNG) для создания ключей.
Внутри он генерирует два связанных ключа: открытый (для шифрования или проверки подписи) и закрытый (для дешифрования или создания подписи).
Размер ключа зависит от алгоритма (например, 2048 или 4096 бит для RSA).


Основные методы KeyPairGenerator

getInstance(String algorithm): Создает экземпляр KeyPairGenerator для указанного алгоритма (например, "RSA").
initialize(int keysize): Устанавливает размер ключа.
generateKeyPair(): Генерирует пару ключей (открытый и закрытый).


Пример использования KeyPairGenerator
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.util.Base64;

public class KeyPairGeneratorExample {
public static void main(String[] args) throws Exception {
// Создание KeyPairGenerator для RSA
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
keyPairGen.initialize(2048); // 2048-битный ключ

// Генерация пары ключей
KeyPair keyPair = keyPairGen.generateKeyPair();

// Получение открытого и закрытого ключей
byte[] publicKey = keyPair.getPublic().getEncoded();
byte[] privateKey = keyPair.getPrivate().getEncoded();

System.out.println("Public Key (Base64): " + Base64.getEncoder().encodeToString(publicKey));
System.out.println("Private Key (Base64): " + Base64.getEncoder().encodeToString(privateKey));
}
}


Плюсы и минусы KeyPairGenerator

Плюсы:
Поддержка различных асимметричных алгоритмов (RSA, DSA, ECDSA).
Простота генерации ключей.


Минусы:
Генерация ключей может быть медленной для больших размеров (например, 4096 бит).
Ключи должны храниться безопасно (например, в KeyStore).


Класс KeyPair (работа с асимметричными ключами)

Класс KeyPair представляет собой контейнер для пары асимметричных ключей: открытого и закрытого. Он используется вместе с KeyPairGenerator и другими классами, такими как Signature и Cipher.

Как работает KeyPair под капотом?
KeyPair содержит два объекта: PublicKey и PrivateKey.
Эти ключи используются в асимметричных операциях, таких как шифрование/дешифрование или создание/проверка цифровых подписей.

Основные методы KeyPair

getPublic(): Возвращает открытый ключ.
getPrivate(): Возвращает закрытый ключ.

Пример использования KeyPair
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;

public class KeyPairExample {
public static void main(String[] args) throws Exception {
// Генерация пары ключей
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
keyPairGen.initialize(2048);
KeyPair keyPair = keyPairGen.generateKeyPair();

// Получение открытого и закрытого ключей
PublicKey publicKey = keyPair.getPublic();
PrivateKey privateKey = keyPair.getPrivate();

System.out.println("Public Key Algorithm: " + publicKey.getAlgorithm());
System.out.println("Private Key Format: " + privateKey.getFormat());
}
}


Плюсы и минусы KeyPair

Плюсы:
Удобный контейнер для работы с парой ключей.
Поддерживает различные алгоритмы.


Минусы:
Ключи должны храниться безопасно.
Не подходит для симметричных ключей.


#Java #Training #Medium #Java_Crypto_API #KeyPairGenerator #KeyPair
Java Crypto API

Класс Signature (цифровые подписи)

Класс Signature используется для создания и проверки цифровых подписей. Цифровая подпись обеспечивает целостность данных и аутентификацию отправителя.

Как работает Signature под капотом?
Signature использует асимметричные алгоритмы (например, RSA, DSA, ECDSA) для создания и проверки подписей.

Процесс состоит из двух этапов:
Создание подписи: Закрытый ключ используется для создания подписи.
Проверка подписи: Открытый ключ используется для проверки подписи.


Основные методы Signature

getInstance(String algorithm): Создает экземпляр Signature для указанного алгоритма (например, "SHA256withRSA").
initSign(PrivateKey privateKey): Инициализирует объект для создания подписи с использованием закрытого ключа.
initVerify(PublicKey publicKey): Инициализирует объект для проверки подписи с использованием открытого ключа.
update(byte[] data): Обновляет данные для подписи или проверки.

sign(): Создает подпись.
verify(byte[] signature): Проверяет подпись.


Пример использования Signature
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;

public class SignatureExample {
public static void main(String[] args) throws Exception {
// Генерация пары ключей
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
keyPairGen.initialize(2048);
KeyPair keyPair = keyPairGen.generateKeyPair();

// Получение ключей
PrivateKey privateKey = keyPair.getPrivate();
PublicKey publicKey = keyPair.getPublic();

// Создание подписи
Signature signature = Signature.getInstance("SHA256withRSA");
signature.initSign(privateKey);
String data = "Hello, Java Crypto!";
signature.update(data.getBytes());
byte[] digitalSignature = signature.sign();
System.out.println("Digital Signature (Base64): " + Base64.getEncoder().encodeToString(digitalSignature));

// Проверка подписи
signature.initVerify(publicKey);
signature.update(data.getBytes());
boolean isVerified = signature.verify(digitalSignature);
System.out.println("Signature Verified: " + isVerified);
}
}


Плюсы и минусы Signature

Плюсы:
Обеспечивает целостность данных и аутентификацию.
Поддерживает различные алгоритмы (RSA, DSA, ECDSA).


Минусы:
Требует наличия пары ключей (открытый и закрытый).
Может быть медленным для больших данных.



Класс MessageDigest (хэш-функции)

Класс MessageDigest используется для вычисления хэш-значений данных. Хэш-функции применяются для обеспечения целостности данных и создания уникальных идентификаторов.

Как работает MessageDigest под капотом?
MessageDigest использует криптографические хэш-функции (например, SHA-256, MD5) для преобразования данных в фиксированный размер хэш-значения.
Хэш-функции являются односторонними: из хэша нельзя восстановить исходные данные.

Основные методы MessageDigest

getInstance(String algorithm): Создает экземпляр MessageDigest для указанного алгоритма (например, "SHA-256").
update(byte[] input): Обновляет данные для хэширования.
digest(): Вычисляет хэш-значение.
digest(byte[] input): Вычисляет хэш-значение для указанных данных.


Пример использования MessageDigest
import java.security.MessageDigest;
import java.util.Base64;

public class MessageDigestExample {
public static void main(String[] args) throws Exception {
// Создание MessageDigest для SHA-256
MessageDigest digest = MessageDigest.getInstance("SHA-256");

// Хэширование данных
String data = "Hello, Java Crypto!";
byte[] hash = digest.digest(data.getBytes());

// Вывод хэша в Base64
System.out.println("Hash (Base64): " + Base64.getEncoder().encodeToString(hash));
}
}


#Java #Training #Medium #Java_Crypto_API #Signature #MessageDigest
Плюсы и минусы MessageDigest

Плюсы:

Обеспечивает целостность данных.
Поддерживает различные алгоритмы (SHA-256, MD5, SHA-1).


Минусы:

Хэш-функции устаревают (например, MD5 и SHA-1 считаются небезопасными).
Не подходит для шифрования данных.


#Java #Training #Medium #Java_Crypto_API #Signature #MessageDigest
Base64 в Java Crypto API

Base64 — это алгоритм кодирования двоичных данных в текстовый формат с использованием 64 символов ASCII. Он используется для представления бинарных данных в виде строк, удобных для передачи по сетевым протоколам и хранения в текстовых форматах. В Java Crypto API Base64 часто применяется для кодирования криптографических ключей, сертификатов и других бинарных данных.

Как работает Base64

Base64 берет 3 байта (24 бита) входных данных и преобразует их в 4 символа из 64-символьного алфавита.

Алфавит Base64 включает:
Латинские буквы: A-Z и a-z (52 символа)
Цифры: 0-9 (10 символов)
Два специальных символа: + и / (или - и _ в URL-совместимой версии)
Заполнитель = (если входные данные не кратны 3 байтам)


Пример кодирования
Допустим, у нас есть строка "Man":

Преобразуем в ASCII-коды:
M = 77, a = 97, n = 110


Переводим в двоичный вид (каждый символ занимает 8 бит):
M     a     n
01001101 01100001 01101110


Разбиваем на 6-битные блоки (24 бита → 4 группы по 6 бит):
010011 010110 000101 101110


Соотносим с таблицей Base64:
010011 → T
010110 → W
000101 → F
101110 → u
Результат кодирования: "TWFu"


Если входные данные не кратны 3 байтам, добавляются =:
"Ma" (2 байта) → TWE=
"M" (1 байт) → TQ==


Base64 в
Java

Java предоставляет встроенный класс Base64 в пакете java.util, начиная с Java 8.

Кодирование строки в Base64
import java.util.Base64;

public class Base64Example {
public static void main(String[] args) {
String originalString = "Hello, Java Crypto API!";
String encodedString = Base64.getEncoder().encodeToString(originalString.getBytes());
System.out.println("Encoded: " + encodedString);
}
}


Вывод:
Encoded: SGVsbG8sIEphdmEgQ3J5cHRvIEFQISTCoA==


Декодирование Base64

import java.util.Base64;

public class Base64DecodeExample {
public static void main(String[] args) {
String encodedString = "SGVsbG8sIEphdmEgQ3J5cHRvIEFQISTCoA==";
byte[] decodedBytes = Base64.getDecoder().decode(encodedString);
String decodedString = new String(decodedBytes);
System.out.println("Decoded: " + decodedString);
}
}


Вывод:
Decoded: Hello, Java Crypto API!


Варианты Base64 в Java

В Java есть три основных варианта Base64:

1. Base64.getEncoder() и Base64.getDecoder() (обычная версия)
Использует стандартный алфавит A-Z, a-z, 0-9, +, / и =.

Пример:
Base64.Encoder encoder = Base64.getEncoder();
Base64.Decoder decoder = Base64.getDecoder();

String encoded = encoder.encodeToString("Test".getBytes());
String decoded = new String(decoder.decode(encoded));

System.out.println("Encoded: " + encoded);
System.out.println("Decoded: " + decoded);


2. Base64.getUrlEncoder() и Base64.getUrlDecoder() (для URL)
Использует безопасный для URL алфавит A-Z, a-z, 0-9, -, _ (заменяет + на - и / на _, убирает =).

Пример:
Base64.Encoder urlEncoder = Base64.getUrlEncoder();
Base64.Decoder urlDecoder = Base64.getUrlDecoder();

String encoded = urlEncoder.encodeToString("https://example.com".getBytes());
String decoded = new String(urlDecoder.decode(encoded));

System.out.println("Encoded URL: " + encoded);
System.out.println("Decoded URL: " + decoded);


3. Base64.getMimeEncoder() и Base64.getMimeDecoder() (для MIME)
Форматирует выходные данные в 76-символьные строки, разделенные \r\n, подходит для шифрования PGP, email-передачи.

Пример:
Base64.Encoder mimeEncoder = Base64.getMimeEncoder();
Base64.Decoder mimeDecoder = Base64.getMimeDecoder();

String encoded = mimeEncoder.encodeToString("Example MIME data".getBytes());
String decoded = new String(mimeDecoder.decode(encoded));

System.out.println("Encoded MIME: " + encoded);
System.out.println("Decoded MIME: " + decoded);


#Java #Training #Medium #Java_Crypto_API #Base64
Где применяется Base64

Передача бинарных данных в текстовом формате
Встраивание изображений в HTML и CSS:
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA..." />

Кодирование бинарных данных в JSON

Шифрование и подписи в криптографии
Используется для кодирования RSA-ключей, хэшей, токенов JWT

Пример работы с шифрованием AES:

byte[] encryptedData = encryptAES("Hello".getBytes(), secretKey);
String base64Encoded = Base64.getEncoder().encodeToString(encryptedData);


HTTP-заголовки и авторизация
Basic Auth:
String auth = "user:password";
String encodedAuth = Base64.getEncoder().encodeToString(auth.getBytes());
String header = "Authorization: Basic " + encodedAuth;


Передача данных по email (MIME)
Base64 используется в email-кодировании, Content-Transfer-Encoding: base64

Сериализация бинарных данных
Применяется для кодирования файлов в JSON, передаваемых через API.

Ограничения и недостатки

Увеличение размера
Base64 увеличивает размер данных на ~33% (3 байта → 4 символа).

Не защищает данные
Base64 — это не шифрование и не хэширование. Оно только преобразует данные в строковый вид, но не защищает их.

Обратимость
Закодированные данные легко декодируются, поэтому Base64 не подходит для хранения паролей.

#Java #Training #Medium #Java_Crypto_API #Base64
Криптографические протоколы (TLS/SSL, HMAC) в Java Crypto API

Криптографические протоколы обеспечивают безопасную передачу данных по сети, защищая их от перехвата, подделки и модификации. В Java Crypto API основными протоколами являются TLS/SSL для защиты соединений и HMAC для проверки целостности данных.

TLS/SSL

TLS (Transport Layer Security) и устаревший SSL (Secure Sockets Layer) — это криптографические протоколы, обеспечивающие безопасное соединение между клиентом и сервером.
TLS заменил SSL, так как SSL имеет уязвимости. На сегодня актуальная версия — TLS 1.3.


Как TLS/SSL защищает соединение

Аутентификация сервера — клиент проверяет подлинность сервера с помощью SSL-сертификата.
Шифрование — передача данных в зашифрованном виде с помощью алгоритмов AES, ChaCha20, RSA.
Целостность — защита данных от подмены с помощью HMAC (Message Authentication Code).


TLS и HTTPS

HTTPS (HyperText Transfer Protocol Secure) — это HTTP + TLS/SSL.
Гарантирует шифрование и проверку подлинности при доступе к сайтам.
В браузере замок означает, что соединение защищено TLS.


Как работает TLS в Java

Java использует библиотеку JSSE (Java Secure Socket Extension) для работы с TLS/SSL.

Установление защищенного HTTPS-соединения

Для отправки HTTPS-запроса в Java используется HttpsURLConnection:
import javax.net.ssl.HttpsURLConnection;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;

public class HttpsClient {
public static void main(String[] args) throws Exception {
URL url = new URL("https://www.example.com");
HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();

// Проверка сертификата
conn.setSSLSocketFactory((SSLSocketFactory) SSLSocketFactory.getDefault());
conn.setRequestMethod("GET");

// Чтение ответа
BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String inputLine;
while ((inputLine = in.readLine()) != null) {
System.out.println(inputLine);
}
in.close();
}
}


Использование своего SSLContext

Для работы с кастомными сертификатами можно использовать SSLContext:
import javax.net.ssl.*;
import java.io.FileInputStream;
import java.security.KeyStore;

public class CustomSSLContext {
public static void main(String[] args) throws Exception {
String keystorePath = "keystore.jks"; // Файл хранилища ключей
String keystorePassword = "password";

// Загрузка ключей
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(new FileInputStream(keystorePath), keystorePassword.toCharArray());

// Инициализация KeyManagerFactory
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
keyManagerFactory.init(keyStore, keystorePassword.toCharArray());

// Создание SSL-контекста
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(keyManagerFactory.getKeyManagers(), null, null);

// Использование SSLContext
SSLSocketFactory socketFactory = sslContext.getSocketFactory();
HttpsURLConnection.setDefaultSSLSocketFactory(socketFactory);
}
}



#Java #Training #Medium #Java_Crypto_API #TLS #SSL
HMAC (Hash-based Message Authentication Code)

HMAC — это механизм проверки целостности данных и аутентификации отправителя.
Основан на криптографических хеш-функциях (SHA-256, SHA-512).
Использует секретный ключ, что делает его безопаснее обычного хеширования.


Как работает HMAC
Клиент и сервер имеют секретный ключ.
Отправитель вычисляет HMAC от сообщения с этим ключом.
Получатель повторно вычисляет HMAC и проверяет совпадение.


Реализация HMAC в Java

Генерация HMAC (SHA-256)

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;

public class HmacExample {
public static void main(String[] args) throws Exception {
String message = "Hello, Java Crypto API!";
String secretKey = "my_secret_key";

// Создание HMAC SHA-256
Mac mac = Mac.getInstance("HmacSHA256");
SecretKeySpec keySpec = new SecretKeySpec(secretKey.getBytes(), "HmacSHA256");
mac.init(keySpec);

// Вычисление HMAC
byte[] hmacBytes = mac.doFinal(message.getBytes());
String hmacBase64 = Base64.getEncoder().encodeToString(hmacBytes);

System.out.println("HMAC (Base64): " + hmacBase64);
}
}


Вывод:
HMAC (Base64): q8phcxg9DpPpMfKkczjRkkv6OiOBv2YoTbYJ46qZaYc=


Проверка HMAC
public static boolean verifyHmac(String message, String receivedHmac, String secretKey) throws Exception {
Mac mac = Mac.getInstance("HmacSHA256");
SecretKeySpec keySpec = new SecretKeySpec(secretKey.getBytes(), "HmacSHA256");
mac.init(keySpec);

// Вычисляем HMAC заново
byte[] hmacBytes = mac.doFinal(message.getBytes());
String computedHmac = Base64.getEncoder().encodeToString(hmacBytes);

// Сравниваем с полученным HMAC
return computedHmac.equals(receivedHmac);
}


Где применяется HMAC


Аутентификация API-запросов
Многие API используют HMAC для подписи запросов (например, AWS, Binance API).
Клиент вычисляет HMAC и отправляет вместе с запросом.
Сервер проверяет правильность HMAC.


Целостность сообщений в TLS/SSL
В TLS 1.2 использовался HMAC для проверки целостности передаваемых данных.

Подпись JSON Web Tokens (JWT)
JWT использует HMAC для подписи (HMAC-SHA256).
Сервер проверяет подпись перед обработкой запроса.


Хранение паролей в базе данных
HMAC можно использовать для защиты паролей перед хешированием.

#Java #Training #Medium #Java_Crypto_API #HMAC