Код программы шифрования данных

Изучив предыдущую статью, я уже знаком с основными операциями с файлами. В этой статье в основном изучается использование языка C для шифрования и дешифрования файлов.

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

Шифрование и дешифрование текстовых файлов

/* Шифрование XOR для каждого символа Правило: 1 ^ 1 = 0, 0 ^ 0 = 0, 1 ^ 0 = 1, 0 ^ 1 = 1 то же, что и 0, отличается от 1 */ void crpypt(char file_path[],char crpypt_path[] )< // открываем файл FILE *file_p = fopen(file_path,»r»); FILE *crpy_p = fopen(crpypt_path,»w»); // Читаем по одному символу за раз char ch; //EOF:end of file while ((ch = fgetc(file_p)) != EOF) < // Запись (операция исключающее ИЛИ) fputc(ch ^ 9, crpy_p); >//неисправность fclose(file_p); fclose(crpy_p); printf(«Шифрование завершено»); > Скопировать код
void main()< char *path = «D:\mytest.txt»; char *crpypt_path = «D:\crpypt_mytest.txt»; char *decrypt_path = «D:\decrpypt_mytest.txt»; crpypt(path,crpypt_path); getchar(); > Скопировать код

Получить зашифрованный файл

Шифруем файлы и пароли аки Царь с GPG и Pass!

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

void decrpypt(char crypt_path[], char decrypt_path[])< // открываем файл FILE *crpypt_p = fopen(crypt_path, «r»); FILE *decrpypt_p = fopen(decrypt_path, «w»); // Читаем по одному символу за раз char ch; //EOF:end of file while ((ch = fgetc(crpypt_p)) != EOF) < // Запись (операция исключающее ИЛИ) fputc(ch ^ 9, decrpypt_p); >//неисправность fclose(crpypt_p); fclose(decrpypt_p); printf(«Расшифровка завершена»); > Скопировать код
void main()< char *path = «D:\mytest.txt»; char *crpypt_path = «D:\crpypt_mytest.txt»; char *decrypt_path = «D:\decrpypt_mytest.txt»; decrpypt(crpypt_path, decrypt_path); getchar(); > Скопировать код

Вышесказанное предназначено для шифрования и дешифрования текстовых файлов, алгоритм: операция XOR над символами текстовых файлов.

Шифрование и дешифрование двоичных файлов

Шифрование двоичных файлов

/* Шифрование и дешифрование двоичных файлов При чтении данных в двоичном файле следует читать по одному символу за раз XOR для каждого символа */ /* Шифрование и дешифрование двоичных файлов При чтении данных в двоичном файле следует читать по одному символу за раз XOR для каждого символа */ void crpypt(char file_path[], char crpypt_path[], char password[])< // открываем файл FILE *file_p = fopen(file_path, «rb»); FILE *crpy_p = fopen(crpypt_path, «wb»); // Читаем по одному символу за раз int ch; int i = 0; // Повторно используем буквы в пароле для операции XOR int pw_len = strlen (password); // Длина пароля while ((ch = fgetc(file_p)) != EOF) < //End of File // Запись (операция исключающее ИЛИ) fputc(ch ^ password[i % pw_len], crpy_p); i++; >//неисправность fclose(file_p); fclose(crpy_p); printf(«Шифрование завершено»); > Скопировать код
/* Пароль: пароль */ void main()< char *path = «D:\timg.jpg»; char *crpypt_path = «D:\crpypt_timg.jpg»; char *decrypt_path = «D:\decrpypt_timg.jpg»; crpypt(path, crpypt_path, «password»); getchar(); > Скопировать код

Расшифровка двоичного файла

Принципы шифрования и криптографии. Расшифруйте послание!


// Расшифровать void decrpypt(char crypt_path[], char decrypt_path[], char password[])< // открываем файл FILE *crpypt_p = fopen(crypt_path, «rb»); FILE *decrpypt_p = fopen(decrypt_path, «wb»); // Читаем по одному символу за раз int ch; // Повторно используем буквы в пароле для операции XOR int i = 0; // Длина пароля int pw_len = strlen(password); //EOF:end of file while ((ch = fgetc(crpypt_p)) != EOF) < // Запись (операция исключающее ИЛИ) fputc(ch ^ password[i % pw_len], decrpypt_p); i++; >//неисправность fclose(crpypt_p); fclose(decrpypt_p); printf(«Расшифровка завершена»); > /* Пароль: пароль */ void main()< char *path = «D:\timg.jpg»; char *crpypt_path = «D:\crpypt_timg.jpg»; char *decrypt_path = «D:\decrpypt_timg.jpg»; decrpypt(crpypt_path, decrypt_path, «password»); getchar(); > Скопировать код

Читайте также:
Программы для создание музыки на Андроид планшет

Здесь для загрузки двоичных файлов и шифрования текстовых файлов используется один и тот же алгоритм: операция XOR.

Примечание. Чтение и запись двоичного файла и текстового файла различаются. Использование чтения и записи текстового файла: «r», «w» Двоичные файлы для чтения и записи используются соответственно: «rb», «wb».

Выше приведен пример использования операции XOR для шифрования и дешифрования файлов.

Источник: russianblogs.com

Pycrypto в Python: шифрование и дешифрование данных

Pycrypto — это модуль Python, предоставляющий криптографические услуги. Модуль Pycrypto представляет собой набор безопасных хэш-функций, таких как RIPEMD160 и SHA256, и различных алгоритмов шифрования, таких как AES, DES, RSA, ElGamal и т. д. Например, AES является быстрым, надежным и фактическим стандартом для симметричного шифрования.

AES-шифрование

Advanced Encryption Standard(AES) — это симметричный блочный шифр.

AES включает в себя три блочных шифра:

AES-128 использует 128-битный ключ для шифрования и дешифрования блока сообщений, AES-192 использует 192-битный ключ, а AES-256 использует 256-битный ключ для шифрования и дешифрования сообщений.

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

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

Ключи любой длины могут использоваться для защиты конфиденциального и секретного уровней. Для совершенно секретной информации требуются 192-битные или 256-битные ключи.

В этом примере мы увидим шифрование AES и дешифрование 16-байтового текста.

Шаги для создания шифрования и дешифрования в Python

Чтобы использовать шифрование и дешифрование AES в Python, мы должны выполнить следующие шаги.

  1. Генерация секретного ключа.
  2. Генерация вектора инициализации.
  3. Создание шифра AES.
  4. Зашифровать сообщение с помощью AES.
  5. Расшифровать сообщение.

Генерация секретного ключа

Шифрование AES требует надежного ключа. Чем сильнее ключ, тем сильнее ваше шифрование. Это, пожалуй, самое слабое звено в цепи. Чтобы сгенерировать секретный ключ, мы будем использовать метод urandom() модуля os.

Функция Python os.urandom() используется для генерации строки случайного размера в байтах, подходящей для криптографического использования, или, можно сказать, этот метод генерирует строку, содержащую случайные символы.

Источник: python-lab.ru

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

Симметричные криптосистемы (симметричное шифрование) — это способ шифрования, в котором один и тот же криптографический ключ применяется для шифрования и дешифровывания. При асимметричном шифровании криптографические ключи шифрования и дешифрирования отличаются; шифрование осуществляется с помощью открытого ключа, а дешифрование с помощью закрытого ключа.

Определение шифра

Рассмотрим реализацию симметричного шифрования в java на примере алгоритма AES. В первую очередь нам понадобится определяющий алгоритм шифрования класс javax.crypto.Cipher, реализующий базовые функции популярных криптографических алгоритомов. Для получения экземпляра данного класса используется статистический метод Cipher.getInstance(), которому в качестве параметра передается наименование криптографического алгоритма шифрования. В простейшем случае пример создания экземпляра Java Cipher мог бы выглядеть следующим образом :

Cipher cipher = Cipher.getInstance(«AES»);

Однако, согласно документации JCA (Java Cryptography Architecture), в разделе «Creating a Cipher Object» указано, что для того, чтобы получить экземпляр Cipher нужно указать не просто алгоритм шифрования, а «трансформацию». Формат описания «трансформации» выглядит следующим образом: «algorithm/mode/padding» :

  • algorithm – наименование алгоритма согласно Cipher (Encryption) Algorithms (в примере используем AES);
  • mode – режим шифрования; например, ECB или CBC (представлены ниже);
  • padding – отступ/разбивка.
Читайте также:
Кто из поэтов выступил с программой нового поэтического течения названного футуризм

Параметр «padding» определяет, какой объём данных составляет 1 блок. Каждый блок данных шифруется отдельно. Так, например, padding, равный PKCS5Padding, определяет размер одного блока в 2 байта (16 бит).

Режимы шифрования

Режим шифрования определяет детали шифрования данных, которые косвенно влияют на алгоритм шифрования. Режимы шифрования могут использоваться в нескольких различных алгоритмах шифрования как метод, добавляемый к основному алгоритму. Поэтому режимы шифрования рассматриваются не отдельно от самих алгоритмов шифрования, а скорее как их «дополнения». Наиболее известные режимы шифрования :

ECB Electronic Codebook (режим электронной кодовой книги)
CBC Cipher Block Chaining (режим сцепления блоков шифротекста)
CFB Cipher Feedback (режим обратной связи по шифротексту)
OFB Output Feedback (режим обратной связи по выходу)
CTR Counter (режим счетчика)

Отдельные алгоритмы шифрования могут работать в разных режимах.

В примере, рассмотренном ниже, при создании экземпляра Cipher будем использовать трансформацию «AES/ECB/PKCS5Padding». То есть, алгоритм шифрования – AES, режим шифрования – ECB, размер блока – 2 байта (PKCS5Padding).

Инициализация шифра

Прежде чем использовать Cipher для шифрования или дешифрирования текста, его необходимо инициализировать. Инициализация Cipher выполняется вызовом его метода init(int opmode, Key key), принимающего два параметра :

  • режим opmode, имеющий одно из значений Cipher.ENCRYPT_MODE или Cipher.DECRYPT_MODE;
  • секретный ключ типа java.security.Key.

Следующий код формирует экземпляр cipher для шифрования текста. Для дешифрирования текста необходимо определить режим Cipher.DECRYPT_MODE.

Cipher cipher = Cipher.getInstance(«AES/ECB/PKCS5Padding»); // Экземпляр cipher для шифрования текста cipher.init(Cipher.ENCRYPT_MODE, secretKey);

Создание секретного ключа

Рассмотрим метод создания секретного ключа createSecretKey(), листинг которого представлен ниже. В методе сначала формируется массив bytes с использованием генератора псевдослучайныйх значений SecureRandom.

После этого для массива bytes создается дайджест сообщения MessageDigest. Размер дайджеста составляет 20 байт, из которых выделяются первые 16 байт методом копирования в новый массив (copyOf) утилитой Arrays. Экземпляр секретного ключа SecretKeySpec создается для алгоритма «AES». Закомментированный в методе код позволяет вывести в консоль сгенерированный массив псевдослучайных значений.

private SecretKeySpec createSecretKey() < SecretKeySpec sks = null; byte[] bytes = new byte[16]; SecureRandom random = new SecureRandom(); random.nextBytes(bytes); // System.out.println(«random : » + // DatatypeConverter.printHexBinary(bytes)); try < MessageDigest md; byte[] key; md = MessageDigest.getInstance(«SHA-1»); key = md.digest(bytes); key = Arrays.copyOf(key, 16); sks = new SecretKeySpec(key, «AES»); >catch (NoSuchAlgorithmException e) < >return sks; >

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

Шифрование и дешифрирование

Для шифрования и дешифрования данных с помощью экземпляра Cipher, используется один из методов update() или doFinal(). Класс Cipher имеет несколько переопределенных методов update() и doFinal(), которые принимают разные параметры. Следующий пример демонстрирует использование метода doFinal() для шифрования текста :

byte[] plainText = «Hello, World!».getBytes(«UTF-8»); byte[] cipherText = cipher.doFinal(plainText); System.out.println(«encrypted text : » + DatatypeConverter.printHexBinary(cipherText));

Для дешифрирования текст будет выглядеть примерно также, за исключением того, что экземпляр Cipher должен быть инициализирован соответствующим образом :

byte[] plainText = cipher.doFinal(cipherText);

Листинг примера CryptoExample

В примере CryptoExample представлены 2 метода : encrypt и decrypt. Исходный код метода createSecretKey рассмотрен выше. Алгоритм функционирования данных методов понятен из представленного выше описания. Дополнительно в методах encrypt и decrypt представлен код шифрования и дешифрирования с использованием утилиты java.util.Base64, которая появилась в Java 8.

Base64 — стандарт кодирования двоичных данных при помощи только 64 символов ASCII. Алфавит кодирования содержит текстово-цифровые латинские символы A-Z, a-z и 0-9 (62 знака) и 2 дополнительных символа, зависящих от системы реализации. Т.е. весь диапазон закодированных символов укладывается в английский алфавит, цифры и двух спецсимволов. Таким образом, из каждых 3 исходных байтов утилита Base64 формирует 4 символа, увеличивая размер текста на Cipher cipher; String transformation = «AES/ECB/PKCS5Padding»; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ public CryptoExample() <>//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ public byte[] encrypt(SecretKeySpec secretKey, byte[] plainText) < try < cipher = Cipher.getInstance(transformation); cipher.init(Cipher.ENCRYPT_MODE, secretKey); return cipher.doFinal(plainText); // return Base64.getEncoder() // .encode(cipher.doFinal(plainText)); >catch (Exception e) < >return null; > //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ public byte[] decrypt(SecretKeySpec secretKey, byte[] encryptedText) < try < cipher = Cipher.getInstance(transformation); cipher.init(Cipher.DECRYPT_MODE, secretKey); return cipher.doFinal(encryptedText); // return cipher.doFinal(Base64.getDecoder() // .decode(encryptedText)); >catch (Exception e) <> return null; > //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ private SecretKeySpec createSecretKey() < // исходный код представлен выше . . . >//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ public static void main(String[] args) throws Exception < CryptoExample cryptoEx = new CryptoExample(); SecretKeySpec key = cryptoEx.createSecretKey(); String text = «decrypt!decrypt!decrypt!decrypt!»; byte[] enc = cryptoEx.encrypt(key, text.getBytes()); System.out.println(«Original text: ‘» + text + «‘»); System.out.println(«Encrypted text :n» + DatatypeConverter.printHexBinary(enc)); byte[] bytes = cryptoEx.decrypt(key, enc); if (bytes != null) < String plainAfter = new String(bytes); System.out.println(«Text after decryption: ‘» + plainAfter + «‘»); >> >

Читайте также:
Почему в Айфоне программы пропадают в облако

Ну, и теперь смотрим на результат выполнения примера. В консоль были выведены следующие сообщения :

random : 992DE79A44047FCD641EC2F9F1A2056D Original text: ‘decrypt!decrypt!decrypt!decrypt!’ Encrypted text : CF2949AFAA65F0E2E8926364D56FBBFA CF2949AFAA65F0E2E8926364D56FBBFA 6C1647F049941345172F0083EF997201 Text after decryption: ‘decrypt!decrypt!decrypt!decrypt!’

Кодированный текст (Encrypted text) для наглядности, разделен на 3 части. После первых 2-х частей из 32 символов вставлены символы пробела и переносом », далее остальная часть кодированного текста.

В принципе, кодированный текст был восстановлен правильно. Но вот сам кодированный текст имеет 2 повторения (блоков также 2; остался неприятный осадок). Как это можно исправить? Можно использовать утилиту Base64, которая преобразует исходный текст и повторений не будет. Для этого можно снять комментарии в методах encrypt, decrypt.

Но мы должны быть уверены, что у пользователя используется Java 8. Проще изменить режим шифрования – CBC (Cipher Block Chaining).

Режим шифрования CBC вводит понятие Initialization Vector, представленный классом IvParameterSpec. В данном режиме результат генерации предыдущего блока используется для генерации следующего.

Но чтобы использовать режим шифрования CBC требуется несложная доработка кода, связанная с инициализацией шифра Cipher. Для этого определяем массив из 16 байт sec_bytes, которые будем заполнять псевдослучайными значениями в конструкторе класса. При нициализации шифра будем использовать этот массив для формирования IvParameterSpec. Ниже представлены изменения кода примера для использования режима CBC.

// String transformation = «AES/ECB/PKCS5Padding»; String transformation = «AES/CBC/PKCS5Padding»; byte[] sec_bytes = new byte[16]; . . . //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ public CryptoUtil() < SecureRandom random = new SecureRandom(); random.nextBytes(sec_bytes); >//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ public byte[] encrypt(SecretKeySpec secretKey, byte[] plainText) < try < cipher = Cipher.getInstance(transformation); if (transformation.contains(«ECB»)) cipher.init(Cipher.ENCRYPT_MODE, secretKey); else < IvParameterSpec ivSpec; ivSpec = new IvParameterSpec(sec_bytes); cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivSpec); >// return Base64.getEncoder() // .encode(cipher.doFinal(plainText)); return cipher.doFinal(plainText); > catch (Exception e) < System.out.println(e.getMessage()); >return null; > //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ public byte[] decrypt(SecretKeySpec secretKey, byte[] encryptedText) < try < cipher = Cipher.getInstance(transformation); if (transformation.contains(«ECB»)) cipher.init(Cipher.DECRYPT_MODE, secretKey); else < IvParameterSpec ivSpec; ivSpec = new IvParameterSpec(sec_bytes); cipher.init(Cipher.DECRYPT_MODE, secretKey, ivSpec); >// return cipher.doFinal(Base64.getDecoder() // .decode(encryptedText)); return cipher.doFinal(encryptedText); > catch (Exception e) < System.out.println(e.getMessage()); >return null; >

После доработки повторения в кодированном тексте отсутствуют, результат шифрования и дешифрирования радует.

random : 5B1E804043C2068B9602285172800C3E Original text: ‘decrypt!decrypt!decrypt!decrypt!’ Encrypted text : F0802F50C5E41CFEE3F1F5EA71224771 8F1BCDF65519472EDCD6DE11FB0E14A1 D3A493CF59D7F2BB197CA90025E05203 Text after decryption: ‘decrypt!decrypt!decrypt!decrypt!’

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

Источник: java-online.ru

Рейтинг
( Пока оценок нет )
Загрузка ...
EFT-Soft.ru