Командная строка – команда Cipher

Шифруем файлы и каталоги

Для шифрования данных мы используем команду: cipher:e за которым следует имя / местоположение файла или каталога.

Вам будет предложено ввести пароль для шифрования

Расшифровывать файлы и каталоги

Чтобы расшифровать данные, мы используем cipher:d за которым следует имя файла или каталога.

Вам будет предложено ввести пароль для расшифровки.

Keyagreement

Java Cryptography Architecture вводит важный инструмент — Key agreement is a protocol. Представлен он классом

Messagedigest

Первое про что упоминается в документации JCA — это MessageDigest.
Вообще Digest на русском будет так же — дайджест и соответствует по смыслу “краткое изложение”. Но в криптографии дайджестом называется хэш-сумма. А ещё можно легко запомнить, что на английском Digest можно перевести ещё как переваривать. Подробнее можно прочитать в документации JCA в разделе “

“.

Как сказано в документации, MessageDigest генерирует фиксированного размера результат, называемый digest или hash.

Хэширование — это односторонняя функция, т.е. если мы что-то захэшировали, то из результата (т.е. из хэша) мы не можем получить первоисточник.

Но если хэшируется одинаковые объекты (например, строки из одинаковых символов), то их хэш должен совпадать. Как сказано в документации, такой хэш называется иногда ещё “контрольной суммой” (checksums) или “цифровым слепком/отпечатком” “digital fingerprints” данных.

Хэширование может выполняться используя разные алгоритмы. Доступные алгоритмы можно посмотреть в документе “

“.

Давайте выполним хэширование и выведем хэш в консоль:


import javax.xml.bind.DatatypeConverter;
import java.security.*;
public class Main {
  public static void main(String[] args) {
    try {
      MessageDigest digester = MessageDigest.getInstance("SHA-512");
      byte[] input = "Secret string".getBytes();
      byte[] digest = digester.digest(input);
      System.out.println(DatatypeConverter.printHexBinary(digest));
    } catch (NoSuchAlgorithmException e) {
      throw new IllegalStateException(e);
    }
  }
}

Хэширование может быть полезно, например, при хранении паролей. Так как хэш вводимого пароля можно сверить с ранее сохранённым хэшем. Если хэши совпали, значит и пароль тоже совпал.

Для ещё более безопасного хэширования используют такое понятие, как “соль” (salt). Соль можно реализовать при помощи класса

.
Перед выполнением метода digest опишем добавление “соли”:


byte[] salt = new byte[16];
SecureRandom.getInstanceStrong().nextBytes(salt);
digester.update(salt);


Но хэш — функция односторонняя. А что делать, если хочется иметь возможность зашифровать и расшифровать?

А. расшифровать файлы

Теперь мы расшифруем наш файл командой ниже:

 # ash cipher:d /root/file.enc
<< cipher >>: Enter decryption password:
<< cipher >>: File decrypted at /root/file

Теперь давайте проверим содержимое нашего файла:

 # cat /root/file
file encrypting with linux cipher tool

Вы можете увидеть содержимое нашего исходного файла.

А. шифрование файлов

Давайте представим, что у нас есть файл с содержанием как показано ниже:

# cat file 
file encrypting with linux cipher tool

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

 ash cipher:e /root/file
&amp;lt;&amp;lt; cipher &amp;gt;&amp;gt;: Enter encryption password: 
&amp;lt;&amp;lt; cipher &amp;gt;&amp;gt;: Confirm encryption password: 
&amp;lt;&amp;lt; cipher &amp;gt;&amp;gt;: File encrypted at /root/file.enc

Со своей стороны я заметил, что при шифровании файла исходный файл отсутствует, присутствует только зашифрованный файл.

Вы можете проверить, как показано ниже.

 # ls -l /root/
total 20
-rw-r--r--. 1 root root 90 Jun 25 19:56 file.enc
drwxr-xr-x. 2 root root 19 Jun 25 18:19 folder

Вы можете посмотреть содержимое файла:

 # cat /root/file.enc

U2FsdGVkX19T dDYuraqLzjsgrazvDTAi0opyeMbfZIuTFRPDsQg/ZXlMHD2Zc A
6 i3iW3rPgl NUjpanJkFA== 

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

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

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

:/>  Программы для очистки компьютера скачать бесплатно на Windows 10

В создании пары ключей нам уже недостаточно KeyGenerator, нам нужен

.

Посмотрим на пример:


import javax.crypto.*;
import java.security.*;
public class Main {
  public static void main(String[] args) throws Exception {
    KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA");
    generator.initialize(1024);
    KeyPair keyPair = generator.generateKeyPair();
    // Encrypt with PRIVATE KEY
    Cipher cipher = Cipher.getInstance("RSA");
    cipher.init(Cipher.ENCRYPT_MODE, keyPair.getPublic());
    byte[] data = cipher.doFinal("Hello!".getBytes());
    // Decrypt with PUBLIC KEY
    cipher.init(Cipher.DECRYPT_MODE, keyPair.getPrivate());
    byte[] result = cipher.doFinal(data);
    System.out.println(new String(result));
  }
}

Тут важно понимать, что используя ассиметричное шифрование мы всегда из KeyPair используем один ключ для шифрования, а другой — для дешифрования. Но т.к. смысл шифрования в том, чтобы расшифровать смог только получатель, то шифруется публичным ключом, а расшифровывается только приватным.

Б. расшифровать каталоги

Чтобы дешифровать каталоги выполните тоже самое только с каталогом, как показано ниже:

 # ash cipher:d folder.tar.gz.enc
<< cipher >>: Enter decryption password:
<< cipher >>: Directory decrypted at folder/

Вы можете увидеть, что наша папка расшифрована.

Теперь давайте проверим содержимое нашей папки:

# ls -l folder/
total 4
-rw-r--r--. 1 root root 11 Jun 25 21:08 essai

Вы можете увидеть, что мы можем теперь нормально работать с нашей исходной папкой.

Б. шифровать папку

Рассмотрим папку ниже:

# ls -ld /root/folder
drwxr-xr-x. 2 root root 19 Jun 25 18:19 /root/folder

Чтобы зашифровать папку, используйте команду ниже:

# ash cipher:e folder/
&amp;lt;&amp;lt; cipher &amp;gt;&amp;gt;: Enter encryption password: 
&amp;lt;&amp;lt; cipher &amp;gt;&amp;gt;: Confirm encryption password: 
&amp;lt;&amp;lt; cipher &amp;gt;&amp;gt;: Directory encrypted at folder.tar.gz.enc

Вы можете видеть, что зашифрованная папка была сжата.

Теперь давайте проверим исходную папку:

# ls -l /root
total 24
-rw-r--r--. 1 root root 90 Jun 25 19:56 file.enc
-rw-r--r--. 1 root root 285 Jun 25 20:17 folder.tar.gz.enc

Мы можем заметить, что исходной папки нет.

Зашифрованная папка имеет расширение сжатого файла, для просмотра его содержимого мы используем команду cat, как показано ниже.

# cat /root/folder.tar.gz.enc 
U2FsdGVkX18WP0Lci6rkCfCruUA2P4UmzaOVzGdD1rt824CfNB8KthA0zLOZZDUl
xroF8q7tTrxR3RJrJesZcC08fzMZ5JtUnNAM7aIg bljPFfep2HyP2XK1nRFk5rr
GTjUhd3ue5KCxUUaGAypLZHvA1LixX4FUFRV68u8G5VFPtaHSqc50E/qhUHClAKj
UlVWCvBtHDkD/DDcw1xjqhQKml5wNMK4N7f5dmaSFuXYBmSrQWcgW00i9URxX6jn
7eRawFYP zbsl30QCWGrxw==

Мы можем попытаться проверить содержимое сжатого файла командой tar.

# tar -t /root/folder.tar.gz.enc 

Вы можете видеть, что невозможно увидеть результатой.Я был вынужден использовать Ctrl-c для управления шелом.

Мы можем попробовать распаковать его.

# tar -zxvf /root/folder.tar.gz.enc

gzip: stdin: not in gzip format
tar: Child returned status 1
tar: Error is not recoverable: exiting now

Вы можете видеть, что у нас есть сообщение об ошибке, потому что папка зашифрована, и мы не можем иметь доступ к ее контенту.

Предисловие

Предлагаю перенестись на время в прошлое. Перед нами Древний Рим. И перед нами Гай Юлий Цезарь, который отправляет своим полководцам послание. Давайте посмотрим, что в этом сообщении:

Что же может это значить:

"ЕСКЕУГЬГМХИФЯ Е УЛП"

?

Давайте откроем Java Online Compiler, например:


class Main {
  public static void main(String[] args) {
    String code = "ЕСКЕУГЬГМХИФЯ Е УЛП";
    for (char symbol : code.toCharArray()) {
      if (symbol != ' ') {
        symbol = (char) (symbol - 3);
      }
      System.out.print(symbol);
    }
  }
}

Перед нами — простейшая реализация “Шифра Цезаря” (Caesar Cipher). Согласно труду древнеримского историка Светония под названием “Жизнь двенадцати цезарей” именно так Цезарь шифровал послания к своим полководцам. И это – один из самых древних упоминаний использования такой вещи, как

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

. Слово “криптография” происходит от древнегреческих слов “скрытый” и “пишу”, т.е. это наука о методах обеспечения конфиденциальности.

В Java есть своя поддержка криптографии и называется она –

Java Cryptography Architecture

(JCA).

Описание можно найти в официальной документации от Oracle — ”

:/>  Как убрать пароль при входе в Windows 10: настройка автовхода | SysAdminTips

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

Расшифровка значений


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

Проводится расшифровывание в отношении заданных папок.

/s: некоторый_каталог

Предусматривает осуществление операции определенного типа по отношению к папке и подпапкам внутри неё.


Проводит операцию в отношении файлов, а также каталогов.

Может возникнуть ситуация, когда в процессе появятся ошибки. Если задать данный параметр, то прекращения работы не произойдёт.

В отношении заданных объектов осуществляется шифровка или дешифровка.

В отчет станут добавляться сведения, имеющие наибольшую важность.


Будет происходить вывод файлов, которые имеют атрибуты «скрытый» или «системный». Если не задавать указанный параметр, то никакие действия с файлами данного типа происходить не будут.

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

Производится обновление ключа для шифровки. Используются текущие ключи по отношению ко всему списку файлов на диске. Следует сказать о том, что допускается применение параметра исключительно с /n.


Не позволяет выполнить обновление колючей.

путь_до_файла

Предполагает указание файла и конкретной папки.

/r:название_без_расширения


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

/w:путь_до_раздела

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

Предусматривается вывод справочных сведений.

Сертификаты

Ну и на сладкое у нас осталось не менее важное — сертификаты.

Обычно сертификаты генерируются при помощи утилиты keytool, входящей в поставку jdk. Подробнее можно прочитать, например, тут: ”

“.

Так же можно прочитать в руководствах от Oracle. Например, тут: ”

“.

Для примера воспользуемся

‘ом:


import sun.security.tools.keytool.CertAndKeyGen;
import sun.security.x509.*;
import java.security.cert.*;
import java.security.*;
// Compiler args: -XDignore.symbol.file
public class Main {
  public static void main(String[] args) throws Exception {
    CertAndKeyGen certGen = new CertAndKeyGen("RSA", "SHA256WithRSA", null);
    // generate it with 2048 bits
    certGen.generate(2048);
    PrivateKey privateKey = certGen.getPrivateKey();
    X509Key publicKey = certGen.getPublicKey();
    // prepare the validity of the certificate
    long validSecs = (long) 365 * 24 * 60 * 60; // valid for one year
    // enter your details according to your application
    X500Name principal = new X500Name("CN=My Application,O=My Organisation,L=My City,C=DE");
    // add the certificate information, currently only valid for one year.
    X509Certificate cert = certGen.getSelfCertificate(principal, validSecs);
    // Public Key from Cert equals Public Key from generator
    PublicKey publicKeyFromCert = cert.getPublicKey();
    System.out.println(publicKeyFromCert.equals(publicKey));
  }
}


Как мы видим, сертификат предоставляет возможность предоставить публичный ключ. У этого способа есть недостаток — мы используем

sun.security

, что считается рискованным, т.к. этот пакет не является частью публичного Java API. Именно поэтому при компиляции необходимо указать параметр —

XDignore.symbol.file

.

Есть ещё один способ — создать сертификат вручную. Минус в том, что используется внутреннее API, которое не задокументировано. Однако, знать про него полезно. Как минимум, потому что наглядно видно, как используется спецификация RFC-2459: ”

“.

Вот пример:

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

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

Для того, чтобы использовать симметричное шифрование нам нужен ключ. Чтоб его получить используем

:/>  Как откатить драйвера видеокарты на Windows 10 |

.
Кроме того, нам понадобится класс, представляющий собой шифр (

).

Как сказано в документации JCA в разделе ”

Creating a Cipher Object

“, чтобы создать Cipher нужно указать в строке не просто алгоритм, а “трансформацию”. Описание трансформации выглядит следующим образом: “algorithm/mode/padding”:

Для примера, возьмём следующую трансформацию:

"AES/ECB/PKCS5Padding"

.

То есть алгоритм шифрования — AES, режим шифрования ECB (сокращение для Electronic Codebook), размер блока – PKCS5Padding. PKCS5Padding говорит, что размер одного блока – 2 байта (16 бит).

Режим шифрования Electronic Codebook предполагает последовательное шифрование каждого из блоков:

Выглядеть в коде это может следующим образом:


import javax.xml.bind.DatatypeConverter;
import javax.crypto.*;
import java.security.Key;
public class Main {
  public static void main(String[] args) throws Exception {
    String text = "secret!!secret!!secret!!secret!!";
    // Generate new key
    KeyGenerator keygen = KeyGenerator.getInstance("AES");
    keygen.init(256);
    Key key = keygen.generateKey();
    // Encrypt with key
    String transformation = "AES/ECB/PKCS5Padding";
    Cipher cipher = Cipher.getInstance(transformation);
    cipher.init(Cipher.ENCRYPT_MODE, key);
    byte[] encrypted = cipher.doFinal(text.getBytes());
    System.out.println(DatatypeConverter.printHexBinary(encrypted));
    // Decrypt with key
    cipher.init(Cipher.DECRYPT_MODE, key);
    String result = new String(cipher.doFinal(encrypted));
    System.out.println(result);
  }
}


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

Синтаксис команды

cipher [{/e|/d}] [/s:некоторый_каталог] [/a] [/i] [/f] [/q] [/h] [/k] [/u[/n]] [путь_до_файла […]] | [/r:название_без_расширения] | [/w:путь_до_раздела]

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

Последнее, о чём хотелось бы поговорить, это о хранилище ключей и сертификатов, которое называется KeyStore. Понятно, что постоянно генерировать сертификаты и ключи — дорого и бессмысленно. Поэтому их надо как-то безопасно хранить. Для этого есть средство — KeyStore. Хранилище ключей описано в документации JCA в главе “

“.

API для работы с ним очень понятное. Вот небольшой пример:


KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(null, null);
String alias = "EntityAlias";
java.security.cert.Certificate[] chain = {certificate};
keyStore.setKeyEntry(alias, keyPair.getPrivate(), "keyPassword".toCharArray(), chain);
// Загрузка содержимого (Private Key   Certificate)
Key key = keyStore.getKey(alias, "keyPassword".toCharArray());
Certificate[] certificateChain = keyStore.getCertificateChain(alias);
// Сохранение KeyStore на диск
File file = File.createTempFile("security_", ".ks");
System.out.println(file.getAbsolutePath());
try (FileOutputStream fos = new FileOutputStream(file)) {
	keyStore.store(fos, "keyStorePassword".toCharArray());
}


Как видно из примера, сначала выполняется

load

для KeyStore. Но в нашем случае мы указали первый атрибут null, т.е. источника для KeyStore нет. Значит KeyStore создаётся пустой, чтобы его дальше сохранить. Второй параметр тоже null, т.к. мы создаём новый KeyStore. Если бы мы загружали KeyStore из файла, то тут нужно было бы указать пароль (по аналогии с методом KeyStore с названием store).

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

Как мы видели выше, зная public key можно отправлять данные так, чтобы их смог расшифровать только владелец private key. То есть суть ассиметричного шифрования в том, что шифрует кто угодно, а читаем только мы. Есть и обратная процедура – цифровая подпись, представленная классом

.

Цифровая подпись может использовать следующие алгоритмы: ”

“.
Документация по JCA предлагает приглядеться к этим двум: DSAwithMD5 и RSAwithMD5

Что лучше DSA или RSA и в чём их отличие можно прочитать здесь: ”

“.

Или почитать обсуждения здесь: ”

“.

Итак, цифровая подпись. Нам потребуется, как и раньше, пара ключей KeyPair и новый класс Signature. Если Вы до сих пор тестировали в онлайн компиляторах, то следующий пример может для них оказаться несколько тяжёлым. У меня пример выполнился только тут:

Оставьте комментарий

Adblock
detector