В криптографии шифр Вернама известен также как «схема одноразовых блокнотов». Решение является системой симметричного шифрования, которая была изобретена в 1917 году сотрудниками AT). Основным объектом рассмотрения в данном методе шифрования является логическая операция XOR (взаимоисключающее ИЛИ).
Таким образом, так как у нас двоичная арифметика, то все операции будут осуществляется над нулем (0) и единицей (1). Логическая операция XOR в отличие от операции OR при логическом сравнении 0 и 1 дает 1, при сравнении 1 с 1 дает 0, а при 0 с 0 дает 0. Следовательно, если мы выполним операцию XOR над числами 10110 и 11010 то получим: 10110 xor 11010 = 01100. Надеюсь что принцип работы операции XOR понятен.
Далее, так как шифр работает с двоичной системой исчисления, необходимо понимать что буквы это всего лишь некоторая интерпретация числа, то есть число является кодом символа некоторой таблицы кодировок. К примеру, наиболее популярные таблицы кодировок это: ANSI, ASCII и UTF(unicode).
Шифраторы, дешифраторы. Назначение, принцип работы, типовые схемы.
Естественно, что в каждой таблицы один и тот же символ может иметь разный код, поэтому во избежании путаницы имейте это ввиду и используйте одну и ту же кодировку при шифровании и дешифровании. Замечу, что использовать можно и свою (придуманную) кодировку. Кроме того, данный шифр может использоваться не только на компьютерах. Его можно применить и к тексту написанному на бумаге. Только перед применением надо сделать некие преобразования.
Таким образом, перед тем как осуществить шифрование необходимо перевести все символы в их однозначную числовую интерпретацию. Если Вы решили применить шифр в компьютерных системах то для вас уже существуют соответствующие кодировки, и язык программирования выбранный Вами скорее всего поддерживает явное или неявное преобразование.
И вам остается только произвести над каждой парой операцию XOR. В различных языках это операция определяется по разному, приведу пример для Pasсal/Delphi/Assembler — xor, C/C++ — ^. Однако, если же Вы решили применить шифр Вернама к письменному тексту, то к примеру дайте каждой букве используемого вами алфавита, соответствующий ей порядковый номер в двоичной системе исчисления.
Например, если вы используете русский алфавит (без учета буквы Ё) то это будет выглядеть так: а -> 00000, б -> 00001, в -> 00010, г -> 00011, … я -> 111111. Тем самым мы определили свою таблицу кодировки. После этого, написав сообщение и придумав ключ, преобразуйте, каждый символ в их числовое значение, соответствующее вашей таблице кодировки, и после этого осуществляйте операцию XOR над каждой соответствующей парой. Так как данный метод шифрования является симметричным, следовательно применив операция XOR каждой паре символов шифр-текста (шифрограммы) и ключа, мы получим открытый текст.
Программная реализация шифра Вернама (C/C++ и Delphi).
На основе изученного материала, я покажу как реализовать шифр Вернама на С/С++ и Pascal/Delphi. Программу целиком писать нет надобность, поэтому будем рассматривать блочную структуру, для того чтобы каждый мог без особого труда заточить ее под сви надобности. А теперь, от слов к делу.
Шифруем файлы с помощью Python
Допусти что у нас есть строка или массив символов — oStr. Это будет открытый текст, который надо зашифровать. Теперь нам надо определить случайный ключ, длиной равной длине открытого текста. Для простоты понимания, мы воспользуемся стандартной функцией генерации случайных чисел: random для Pascal/Delphi и rand для C/C++.
Но замечу сразу что это не лучший вариант, в случае если вы хотите реализовать действительно стойкий шифр. Данный пример выбран из соображения простоты. Теперь покажем как это будет выглядеть в исходном коде:
Источник: zetblog.ru
Русские Блоги
В жизни иногда нам нужно зашифровать некоторые важные файлы. Python предоставляет простые в использовании библиотеки шифрования, такие как hashlib и base64.
Для ежедневного обучения мы можем реализовать простую программу шифрования файлов с помощью операции XOR, чтобы улучшить наши возможности программирования.
Следуйте за публичным аккаунтом WeChat: Эффективное программирование на Python , пойми больше
Базовые знания
Оператор XOR в Python: ^ , Также может быть записано как XOR. Побитовое исключающее ИЛИ означает: исключающее ИЛИ одного и того же значения равно 0, а исключающее ИЛИ разных значений равно 1. В частности, есть четыре возможности: 0 ^ 0 = 0, 0 ^ 1 = 1, 1 ^ 0 = 1, 1 ^ 1 = 0. Мы также можем подытожить закон (A равно 0 или 1): исключающее ИЛИ для 0 и A является самим A; исключающее ИЛИ для 1 и A является противоположностью A.
Давайте посмотрим на свойства, которым удовлетворяет двоичное число:
- Само значение XOR двоичного числа равно 0
- Операция XOR удовлетворяет коммутативному закону
a ^ b ^ c = a ^ (b ^ c) = (a ^ b) ^ c
- Исключающее ИЛИ 0 и a является
(a ^ b) ^ b = a ^ (b ^ b) = a ^ 0 = a
Легко понять, что указанные выше свойства выполняются для любого длинного двоичного числа.
принцип
Понимая природу операции XOR, принцип шифрования становится очень ясным.
Операция шифрования:
Сначала преобразуйте файл в двоичное число, затем сгенерируйте случайный ключ той же длины, что и двоичное число, и выполните операцию XOR над двоичным числом и ключом, чтобы получить зашифрованное двоичное число.
Операция расшифровки:
Выполните XOR зашифрованной двоичной программы с ключом для получения исходного двоичного числа и, наконец, восстановите исходное двоичное число в текстовый файл.
Код
Сгенерируйте случайный ключ:
Библиотека секретов — это модуль псевдослучайных чисел, представленный в Python 3.6, подходящий для генерации случайных ключей. Функция token_bytes принимает параметр типа int, чтобы указать длину случайной байтовой строки. int.from_bytes преобразует байтовую строку в int, то есть необходимое нам двоичное число.
from secrets import token_bytes from typing import Tuple def random_key(length:int) -> int: key:bytes = token_bytes(nbytes=length) key_int:int = int.from_bytes(key, ‘big’) return key_int
Блок шифрования:
Функция encrypt принимает объект str и возвращает кортеж (int, int). С помощью метода кодирования мы кодируем строку в байтовую строку. Функция int.from_bytes преобразует байтовую строку в объект типа int. Наконец, двоичный объект и случайный ключ подвергаются операции XOR, и получается зашифрованный текст.
def encrypt(raw:str) -> Tuple[int, int]: raw_bytes:bytes = raw.encode() raw_int:int = int.from_bytes(raw_bytes, ‘big’) key_int:int = random_key(len(raw_bytes)) return raw_int ^ key_int, key_int
Блок дешифрования:
decrypt принимает два объекта типа int, которые представляют собой зашифрованный текст и случайный ключ. Сначала выполните операцию исключающего ИЛИ над двумя, чтобы вычислить количество бит, занятых расшифрованным объектом int. Функция decrypted.bit_length получает количество цифр двоичного числа. Разделите на 8, чтобы получить размер в битах.
Чтобы предотвратить это, двоичное число 1 ~ 7 делит 8, чтобы получить 0, поэтому добавляется 7, а затем 8 делится. Используйте функцию int.to_bytes для преобразования расшифрованного объекта int в объект байтов. Наконец, байтовая строка преобразуется в строку с помощью метода декодирования.
def decrypt(encrypted:int, key_int:int) -> str: decrypted:int = encrypted ^ key_int length = (decrypted.bit_length() + 7) // 8 decrypted_bytes:bytes = int.to_bytes(decrypted, length, ‘big’) return decrypted_bytes.decode()
Используя вышеуказанные функции, мы можем легко зашифровать и расшифровать текстовые файлы.
>>> raw = «Нарисуй картину и узнай лицо весеннего бриза, звенящего в небо и вернись в душу ночи и луны» >>> encrypted = encrypt(raw) >>> encrypted (217447100157746604585, 9697901906831571319) >>> decrypt(*encrypted) «Нарисуй картину и узнай лицо весеннего бриза, звенящего в небо и вернись в душу ночи и луны»
Зашифрованный текстовый файл
path — это адрес файла, который нужно зашифровать.Если адрес ключа не указан, в этом каталоге будут созданы новый каталог и файл.
import json from pathlib import Path def encrypt_file(path:str, key_path=None, *, encoding=’utf-8′): path = Path(path) cwd = path.cwd() / path.name.split(‘.’)[0] path_encrypted = cwd / path.name if key_path is None: key_path = cwd / ‘key’ if not cwd.exists(): cwd.mkdir() path_encrypted.touch() key_path.touch() with path.open(‘rt’, encoding=encoding) as f1, path_encrypted.open(‘wt’, encoding=encoding) as f2, key_path.open(‘wt’, encoding=encoding) as f3: encrypted, key = encrypt(f1.read()) json.dump(encrypted, f2) json.dump(key, f3)
Расшифровать файлы
def decrypt_file(path_encrypted:str, key_path=None, *, encoding=’utf-8′): path_encrypted = Path(path_encrypted) cwd = path_encrypted.cwd() path_decrypted = cwd / ‘decrypted’ if not path_decrypted.exists(): path_decrypted.mkdir() path_decrypted /= path_encrypted.name path_decrypted.touch() if key_path is None: key_path = cwd / ‘key’ with path_encrypted.open(‘rt’, encoding=encoding) as f1, key_path.open(‘rt’, encoding=encoding) as f2, path_decrypted.open(‘wt’, encoding=encoding) as f3: decrypted = decrypt(json.load(f1), json.load(f2)) f3.write(decrypted)
После выполнения операций шифрования и дешифрования файла полученный расшифрованный файл будет таким же, как и исходный файл. Принципиальная схема выглядит следующим образом:
В официальной учетной записи WeChat: Эффективное программирование на Python , Фоновый ответ 2019517, вы можете получить исходный код.
Источник: russianblogs.com