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

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

Наш канал на RUTube - https://rutube.ru/channel/37896292/
Download Telegram
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
This media is not supported in your browser
VIEW IN TELEGRAM
айтишник отказался от зарплаты в 950 тысяч рублей, потому что… ЖЕНА БЫ НЕ ПОНЯЛА зарплату меньше миллиона.

https://t.me/Java_for_beginner_dev

#Mems
Что выведет код?

public class Task250225 {
public static void main(String[] args) {
byte b = (byte) 200;
int i = b + 100;
double d = (double) i / 300;

System.out.println(b);
System.out.println(i);
System.out.println(d);
}
}


#Tasks
Все сеньоры когда-то были джунами...😂 🤣

https://t.me/Java_for_beginner_dev

#Mems
Please open Telegram to view this post
VIEW IN TELEGRAM
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
#Mems. Все мы немного этот котик
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
Все знают, что он существует, но лично никто не видел...

https://t.me/Java_for_beginner_dev

#Mems
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
Что выведет код

public class Task260225 {
public static void main(String[] args) {
String value = "10";
print(value);
print((byte) value);
print((Object) value);
}

public static void print(String x) {
System.out.println("String");
}

public static void print(byte x) {
System.out.println("byte");
}

public static void print(Object x) {
System.out.println("Object");
}
}


#Tasks
#Mems. Сеньор разработчик решил воспользоваться секретным заклинанием.
Интересно остались ли те кто сам пишет код? 🧐 🤣

https://t.me/Java_for_beginner_dev

#Mems
Please open Telegram to view this post
VIEW IN TELEGRAM
Вопросы с собеседования 👩‍💻

Что такое default метод в интерфейсе?
Anonymous Quiz
2%
Абстрактный метод
4%
Статический метод
93%
Метод с реализацией по умолчанию
0%
Приватный метод
Криптографические протоколы (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