Как зашифровать файл java

Обновлено: 06.07.2024

Криптография имеет дело с фактической защитой цифровых данных. Это относится к разработке механизмов, основанных на математических алгоритмах, которые предоставляют фундаментальные услуги информационной безопасности. Вы можете думать о криптографии как о создании большого инструментария, содержащего различные методы в приложениях безопасности.

Что такое криптоанализ?

Искусство и наука взлома зашифрованного текста называется криптоанализом.

Криптоанализ является родственным разделом криптографии, и они оба сосуществуют. Криптографический процесс приводит к зашифрованному тексту для передачи или хранения. Он предполагает изучение криптографического механизма с намерением их взломать. Криптоанализ также используется при разработке новых криптографических методов для проверки их надежности.

Примитивы криптографии

Криптография на Java

Используя JCA, разработчики могут создавать свои приложения, интегрируя в них безопасность.

Чтобы интегрировать безопасность в свои приложения, а не в зависимости от сложных алгоритмов безопасности, вы можете легко вызывать соответствующие API, предоставляемые в JCA для требуемых услуг.

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

Шаг 1. Создайте объект MessageDigest

Класс MessageDigest предоставляет метод с именем getInstance () . Этот метод принимает переменную String, указывающую имя используемого алгоритма, и возвращает объект MessageDigest, реализующий указанный алгоритм.

Создайте объект MessageDigest, используя метод getInstance (), как показано ниже.

Шаг 2: Передайте данные в созданный объект MessageDigest

пример

Выход

Создание MAC

Шаг 1. Создайте объект KeyGenerator

Класс KeyGenerator предоставляет метод getInstance (), который принимает переменную String, представляющую требуемый алгоритм генерации ключей, и возвращает объект KeyGenerator, который генерирует секретные ключи.

Создайте объект KeyGenerator, используя метод getInstance (), как показано ниже.

Шаг 2: Создайте объект SecureRandom

Класс SecureRandom пакета java.Security предоставляет мощный генератор случайных чисел, который используется для генерации случайных чисел в Java. Создайте этот класс, как показано ниже.

Шаг 3: Инициализируйте KeyGenerator

Класс KeyGenerator предоставляет метод с именем init (), этот метод принимает объект SecureRandom и инициализирует текущий KeyGenerator .

С помощью этого метода инициализируйте объект KeyGenerator, созданный на предыдущем шаге.

Шаг 4: Генерация ключа

Сгенерируйте ключ с помощью метода generateKey () класса KeyGenerator, как показано ниже.

Шаг 5: Инициализируйте объект Mac

Метод init () класса Mac принимает объект Key и инициализирует текущий объект Mac, используя заданный ключ.

Шаг 6: Завершите операцию Mac

Метод doFinal () класса Mac используется для завершения операции Mac. Передайте в этот метод необходимые данные в виде байтового массива и завершите операцию, как показано ниже.

пример

Выход

Принципиально существует два типа ключей / криптосистем, основанных на типе алгоритмов шифрования-дешифрования.

Шифрование симметричного ключа

Процесс шифрования, в котором для шифрования и дешифрования информации используются одни и те же ключи, называется Symmetric Key Encryption.

Исследование симметричных криптосистем называется симметричной криптографией . Симметричные криптосистемы также иногда называют криптосистемами с секретным ключом .

Ниже приведены несколько распространенных примеров шифрования с симметричным ключом:

  • Стандарт цифрового шифрования (DES)
  • Triple-DES (3DES)
  • IDEA
  • BLOWFISH

Асимметричное шифрование ключа

Процесс шифрования, в котором для шифрования и дешифрования информации используются разные ключи, называется асимметричным шифрованием ключей. Хотя ключи разные, они математически связаны и, следовательно, возможно получение открытого текста путем расшифровки зашифрованного текста.

Используемые / генерируемые ключи и сертификаты хранятся в базе данных, называемой хранилищем ключей. По умолчанию эта база данных хранится в файле с именем .keystore .

Вы можете получить доступ к содержимому этой базы данных, используя класс KeyStore пакета java.security . Это управляет тремя различными записями, а именно: PrivateKeyEntry, SecretKeyEntry, TrustedCertificateEntry.

  • PrivateKeyEntry
  • SecretKeyEntry
  • TrustedCertificateEntry

Хранение ключа в хранилище ключей

В этом разделе мы узнаем, как хранить ключ в хранилище ключей. Чтобы сохранить ключ в хранилище ключей, выполните следующие действия.

Шаг 1: Создать объект KeyStore

Метод getInstance () класса KeyStore пакета java.security принимает строковое значение, представляющее тип хранилища ключей, и возвращает объект KeyStore.

Создайте объект класса KeyStore с помощью метода getInstance (), как показано ниже.

Шаг 2: Загрузите объект KeyStore

Метод load () класса KeyStore принимает объект FileInputStream, представляющий файл хранилища ключей, и параметр String, указывающий пароль хранилища ключей.

Шаг 3. Создайте объект KeyStore.ProtectionParameter.

Создайте параметр KeyStore.ProtectionParameter, как показано ниже.

Шаг 4: Создайте объект SecretKey

Создайте объект SecretKey (interface) путем создания экземпляра его подкласса SecretKeySpec . При создании экземпляра вам необходимо передать пароль и алгоритм в качестве параметров его конструктору, как показано ниже.

Шаг 5: Создайте объект SecretKeyEntry

Создайте объект класса SecretKeyEntry , передав объект SecretKey, созданный на предыдущем шаге, как показано ниже.

Шаг 6: Установите запись в хранилище ключей

Метод setEntry () класса KeyStore принимает параметр String, представляющий псевдоним записи хранилища ключей, объект SecretKeyEntry, объект ProtectionParameter и сохраняет запись под указанным псевдонимом.

Установите запись в хранилище ключей, используя метод setEntry (), как показано ниже.

В следующем примере ключи хранятся в хранилище ключей, существующем в файле «cacerts» (операционная система Windows 10).

В этой главе мы узнаем, как извлечь ключ из хранилища ключей с помощью Java Cryptography.

Чтобы получить ключ из хранилища ключей, выполните действия, указанные ниже.

Шаг 1: Создать объект KeyStore

Метод getInstance () класса KeyStore пакета java.security принимает строковое значение, представляющее тип хранилища ключей, и возвращает объект KeyStore.

Создайте объект класса KeyStore, используя этот метод, как показано ниже.

Шаг 2: Загрузите объект KeyStore

Метод load () класса KeyStore принимает объект FileInputStream, представляющий файл хранилища ключей, и параметр String, указывающий пароль хранилища ключей.

Шаг 3. Создайте объект KeyStore.ProtectionParameter.

Создайте параметр KeyStore.ProtectionParameter, как показано ниже.

Шаг 4: Создайте объект SecretKey

Создайте объект SecretKey (interface) путем создания экземпляра его подкласса SecretKeySpec . При создании экземпляра вам необходимо передать пароль и алгоритм в качестве параметров его конструктору, как показано ниже.

Шаг 5: Создайте объект SecretKeyEntry

Создайте объект класса SecretKeyEntry , передав объект SecretKey, созданный на предыдущем шаге, как показано ниже.

Шаг 6: установить запись в хранилище ключей

Метод setEntry () класса KeyStore принимает параметр String, представляющий псевдоним записи хранилища ключей, объект SecretKeyEntry, объект ProtectionParameter и сохраняет запись под указанным псевдонимом.

Установите запись в хранилище ключей, используя метод setEntry (), как показано ниже.

В данной статье говорится о том, как осуществить шифрование с помощью алгоритма AES-256 на Java.

Как уже говорилось ранее, AES-256 представляет собой алгоритм шифрования с симметричным ключом. Это означает, что для шифрования и дешифрования используется один и тот же криптографический ключ.

Как зашифровать и дешифровать с помощью AES-256 средствами Java

Класс для шифрования и дешифрования потока байт на Java может выглядеть следующим образом:

В конструкторе Aes256Class ( ) инициализируется объект keyGenerator , которому задается размер ключа 256 бит. Далее с помощью функции generateKey() генерируется случайный ключ с заданным размером (256 бит).

В функцию makeAes передается исходный массив байт и режим работы объекта класса Cipher:

Cipher.ENCRYPT_MODE либо Cipher.DECRYPT_MODE.

В классе с функцией main можем вызвать описанные выше методы следующим образом:

Получаем следующий результат:

Java AES

Объясняю, зачем я зациклил выполнение функции makeAes.

Благодаря шифрованию и дешифрованию одного и того же текста несколько раз, можно увидеть, что шифр получается один и тот же, что не есть хорошо.

Функция приобретет следующий вид:

Вызываем функцию makeAes в методе main:

Java AES with salt

Реализация AES-256 на Java с помощью фреймворка Spring Security

В данной статье приведу реализацию AES с помощью Java фреймворка Spring Security:

Результат работы кода:

AES Spring Security

Как видите, реализация AES-256 от Spring Security не подводит. Как знать, что это именно AES? В официальной документации есть такое упоминание:

The "standard" encryption method is 256-bit AES (Spring Crypto Module)

Можете попробовать перебором паролей, если у вас в запасе есть сотни миллиардов лет.

Безопасность обмена данными — одно из важнейших свойств современных приложений. С древних времён люди придумывали хитрые способы, которые с развитием человечества стали целой наукой Криптографией. Естественно, Java не осталась в стороне и предложила разработчикам Java Cryptography Architecture (JCA). Данный обзор должен дать первые представления о том, как это работает.

Предисловие

Что же может это значить: "ЕСКЕУГЬГМХИФЯ Е УЛП" ? Давайте откроем Java Online Compiler, например: repl.it Перед нами — простейшая реализация "Шифра Цезаря" (Caesar Cipher). Согласно труду древнеримского историка Светония под названием "Жизнь двенадцати цезарей" именно так Цезарь шифровал послания к своим полководцам. И это - один из самых древних упоминаний использования такой вещи, как Криптография. Слово "криптография" происходит от древнегреческих слов "скрытый" и "пишу", т.е. это наука о методах обеспечения конфиденциальности. В Java есть своя поддержка криптографии и называется она - Java Cryptography Architecture (JCA). Описание можно найти в официальной документации от Oracle — "Java Cryptography Architecture (JCA)". Предлагаю посмотреть, какие возможности мы получаем благодаря JCA.

Как мы уже ранее узнали, в Java для работы с криптографией предлагает Java Cryptography Architecture (JCA). Данная архитектура содержит API (т.е. некоторый набор интерфейсов) и провайдеры (которые их реализуют):

Как сказано в документации, "The Java platform includes a number of built-in providers". То есть платформа Java предоставляет набор встроенных провайдеров, которые при необходимости можно дополнить. Это можно увидеть самим: Зарегистрировать сторонний провайдер очень просто. Например: Security.addProvider(new BouncyCastleProvider()); Данный пример подключает один из самых известных провайдеров — BouncyCastle. Но в данном обзоре мы будем пользоваться только базовыми средствами, без сторонних библиотек. Наш основной документ: "Java Cryptography Architecture (JCA)". Понимание работы JCA поможет проще понять технологии, в рамках которых активно используется этот самый JCA. Например: HTTPS (см. "От HTTP до HTTPS").

MessageDigest

Первое про что упоминается в документации JCA — это MessageDigest. Вообще Digest на русском будет так же — дайджест и соответствует по смыслу "краткое изложение". Но в криптографии дайджестом называется хэш-сумма. А ещё можно легко запомнить, что на английском Digest можно перевести ещё как переваривать. Подробнее можно прочитать в документации JCA в разделе "MessageDigest". Как сказано в документации, MessageDigest генерирует фиксированного размера результат, называемый digest или hash. Хэширование — это односторонняя функция, т.е. если мы что-то захэшировали, то из результата (т.е. из хэша) мы не можем получить первоисточник. Но если хэшируется одинаковые объекты (например, строки из одинаковых символов), то их хэш должен совпадать. Как сказано в документации, такой хэш называется иногда ещё "контрольной суммой" (checksums) или "цифровым слепком/отпечатком" "digital fingerprints" данных. Хэширование может выполняться используя разные алгоритмы. Доступные алгоритмы можно посмотреть в документе "Java Cryptography Architecture Standard Algorithm Name Documentation for JDK 8". Давайте выполним хэширование и выведем хэш в консоль: Хэширование может быть полезно, например, при хранении паролей. Так как хэш вводимого пароля можно сверить с ранее сохранённым хэшем. Если хэши совпали, значит и пароль тоже совпал. Для ещё более безопасного хэширования используют такое понятие, как "соль" (salt). Соль можно реализовать при помощи класса SecureRandom. Перед выполнением метода digest опишем добавление "соли": Но хэш — функция односторонняя. А что делать, если хочется иметь возможность зашифровать и расшифровать?

Симметричное шифрование (symmetric key cryptography)

  • Алгоритм: тут смотрим в стандартных именах для "Cipher (Encryption) Algorithms". Рекомендуется использовать AES.
  • Режим: режим шифрования. Например: ECB или CBC (об этом мы поговорим чуть дальше)
  • Отступ/разбивка: каждый блок данных шифруется отдельно. Данный параметр определяет, какой объём данных считать за 1 блок.

Выглядеть в коде это может следующим образом: Если мы выполним, то ожидаемо увидим повтор, т.к. мы указали 32 символа. Эти символы составляют 2 блока по 16 бит:

Чтобы избежать в таком случае повтора следует использовать другой режим — Cipher Block Chaining (CBC). Данный режим вводит понятие Initialization Vector (представлен классом IvParameterSpec). А так же благодаря этому режиму результат генерации прошлого блока будет использован для генерации следующего:

Напишем теперь это в коде: Как мы видим — в результате мы не видим повторяющихся блоков шифра. По этой причине режим ECB не рекомендуется, т.к. даёт возможность увидеть повторы и использовать это знание для дешифровки. Подробнее про ECB и CBC советую прочитать материал: "Режим электронной кодовой книги". Но симметричное шифрование имеет очевидную проблему - нужно как-то передать ключ от того, кто шифрует, тому, кто шифрует. И на этом пути этот ключ можно перехватить и тогда будет возможность перехватывать данные. И эту проблему призвано решить ассиметричное шифрование.

Ассиметричное шифрование (asymmetric cryptography)

Ассиметричное шифрование или же Public-key cryptography — это такой способ шифрования, при котором используется пара ключей: private key (хранится от всех в секрете) и public key (доступен публично). Такое разделение нужно для того, чтобы безопасно обмениваться открытым ключом между сторонами обмена информацией, при этом хранить секретный ключ в безопасности. В создании пары ключей нам уже недостаточно KeyGenerator, нам нужен KeyPairGenerator. Посмотрим на пример: Тут важно понимать, что используя ассиметричное шифрование мы всегда из KeyPair используем один ключ для шифрования, а другой — для дешифрования. Но т.к. смысл шифрования в том, чтобы расшифровать смог только получатель, то шифруется публичным ключом, а расшифровывается только приватным.

Цифровая подпись

Выше мы увидели, как стороны обмениваются данными. Нет ли какого-то стандартного интерфейса для этого взаимодействия, предусмотренного в JCA? Оказывается - есть. Давайте рассмотрим его.

KeyAgreement

Сертификаты

Ну и на сладкое у нас осталось не менее важное — сертификаты. Обычно сертификаты генерируются при помощи утилиты keytool, входящей в поставку jdk. Подробнее можно прочитать, например, тут: "Generating a self-signed SSL certificate using the Java keytool command". Так же можно прочитать в руководствах от Oracle. Например, тут: "To Use keytool to Create a Server Certificate". Для примера воспользуемся Tutorialspoint Java Online Compiler'ом: Как мы видим, сертификат предоставляет возможность предоставить публичный ключ. У этого способа есть недостаток — мы используем sun.security , что считается рискованным, т.к. этот пакет не является частью публичного Java API. Именно поэтому при компиляции необходимо указать параметр — XDignore.symbol.file . Есть ещё один способ — создать сертификат вручную. Минус в том, что используется внутреннее API, которое не задокументировано. Однако, знать про него полезно. Как минимум, потому что наглядно видно, как используется спецификация RFC-2459: "Internet X.509 Public Key Infrastructure". Вот пример:

Хранилище ключей (KeyStore)

Последнее, о чём хотелось бы поговорить, это о хранилище ключей и сертификатов, которое называется KeyStore. Понятно, что постоянно генерировать сертификаты и ключи — дорого и бессмысленно. Поэтому их надо как-то безопасно хранить. Для этого есть средство — KeyStore. Хранилище ключей описано в документации JCA в главе "KeyManagement". API для работы с ним очень понятное. Вот небольшой пример: Как видно из примера, сначала выполняется load для KeyStore. Но в нашем случае мы указали первый атрибут null, т.е. источника для KeyStore нет. Значит KeyStore создаётся пустой, чтобы его дальше сохранить. Второй параметр тоже null, т.к. мы создаём новый KeyStore. Если бы мы загружали KeyStore из файла, то тут нужно было бы указать пароль (по аналогии с методом KeyStore с названием store).

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

В этом примере используется AES GCM для выполнения шифрования AES строки и файла. Примеры включали шифрование AES на основе паролей.

В этой статье показано несколько примеров шифрования и дешифрования Java AES:

  • Шифрование строк AES – (шифрование и расшифровка строки).
  • Шифрование на основе пароля AES – (секретный ключ будет получен из заданного пароля).
  • Шифрование файлов AES. (на основе пароля).

В этой статье мы сосредоточимся на 256-битном шифровании AES с Режимом счетчика Галуа (GCM) .

Не используйте режим электронной кодовой книги AES (ECB) Режим AES ECB или AES/ECB/PKCS5Padding AES/ECB/PKCS5Padding//Режим AES//ECB//(в Java) не является семантически безопасным – Зашифрованный в ECB зашифрованный текст может привести к утечке информации об открытом тексте. Вот дискуссия о Почему я не должен использовать шифрование ECB?

Для шифрования и дешифрования AES нам нужны следующие входные данные:

Лучшая практика шифрования AES Не используйте повторно капельницу с одним и тем же ключом.

1.1 IV (начальное значение или начальный вектор), это случайные байты, обычно 12 байт или 16 байт. В Java мы можем использовать SecureRandom для генерации случайного IV.

1.2 Секретный ключ AES, либо AES-128 , либо AES-256 . В Java мы можем использовать Генератор ключей для генерации секретного ключа AES.

1.3 Секретный ключ AES, полученный из заданного пароля. В Java мы можем использовать SecretKeyFactory и PBKDF2WithHmacSHA256 для генерации ключа AES из заданного пароля.

Мы используем соль для защиты от атак rainbow, и это тоже случайный байт, мы можем использовать тот же 1.1 получите случайный Nonce , чтобы сгенерировать его.

1.4 Мы группируем вышеперечисленные методы в один класс util , чтобы не повторять один и тот же код снова и снова.

2. Шифрование и дешифрование AES.

AES-GCM является наиболее широко используемым аутентифицированным шифром. В этом примере будет зашифрована и расшифрована строка с использованием 256-битного AES в Режиме счетчика Галуа (GCM) .

  • Секретный ключ AES (256 бит)
  • IV – 96 бит (12 байт)
  • Длина (в битах) тега аутентификации – 128 бит (16 байт)

2.1 В Java мы используем AES/GCM/NoPadding для представления алгоритма AES-GCM . Для зашифрованного вывода мы добавляем 16 байт IV к зашифрованному тексту (зашифрованному тексту), потому что нам нужен тот же IV для расшифровки.

В этом примере для шифрования обычного текста будет использоваться AES Привет, мир AES-GCM и позже расшифруйте его обратно в исходный обычный текст.

Простой текст: Привет, Мир AES-GCM

3. Шифрование и дешифрование на основе паролей AES.

Для шифрования на основе пароля мы можем использовать Спецификацию криптографии на основе пароля (PKCS), определенную RFC 8018 , для генерации ключа из заданного пароля.

Для входов PKCS:

  • Пароль, вы предоставляете это.
  • Соль – Не менее 64 бит (8 байт) случайных байтов.
  • Количество итераций – Рекомендуется минимальное количество итераций 1000.

Что такое соль и количество итераций?

  • соль создает широкий набор ключей для данного пароля. Например, если соль составляет 128 бит, для каждого пароля будет целых 2^128 ключей. Поэтому это увеличивает сложность радужных атак. Кроме того, радужная таблица, которую злоумышленники создают для пароля одного пользователя, стала бесполезной для другого пользователя.
  • Количество итераций увеличивает стоимость получения ключей из пароля, следовательно, увеличивает сложность и замедляет скорость атак.

3.1 Для зашифрованного вывода мы добавим 12 байт IV и соль пароля к зашифрованному тексту, потому что для расшифровки нам нужны те же IV и соль пароля (для секретного ключа). Кроме того, мы используем кодировщик Base64 для кодирования зашифрованного текста в строковое представление, чтобы мы могли отправлять зашифрованный текст или зашифрованный текст в строковом формате (массив байтов was).

3.2 Если пароль не совпадает, Java выдает Исключение AEADBadTagException: Несоответствие тегов!

4. Шифрование и расшифровка файлов AES.

Этот пример представляет собой шифрование файлов на основе пароля AES. Идеи те же, но нам нужны некоторые классы ввода-вывода для работы с ресурсами или файлами.

Вот текстовый файл в папке ресурсы .

4.1 Этот пример аналогичен 3.1 EncryptorAesGcmPassword.java , с некоторыми незначительными изменениями, такими как возврат байта[] вместо строки в кодировке base64.

Добавить зашифровать файл и расшифровать файл для работы с файлом.

4.2 Прочитайте вышеизложенное readme.txt файл из пути к классу, зашифруйте его и зашифрованные данные в новый файл c:\test\readme.encrypted.txt .

4.3 Прочитайте зашифрованный файл, расшифруйте его и распечатайте выходные данные.

Читайте также: