Учебники

Криптография с Python — Краткое руководство

Криптография с Python — Обзор

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

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

Терминология криптографии

Часто используемые термины в криптографии объясняются здесь —

Простой текст

Текстовое сообщение — это текст, который читается и понятен всем пользователям. Простой текст — это сообщение, которое подвергается криптографии.

Шифрованный текст

Шифрованный текст — это сообщение, полученное после применения криптографии к простому тексту.

шифрование

Процесс преобразования простого текста в зашифрованный текст называется шифрованием. Это также называется кодированием.

Дешифрирование

Процесс преобразования зашифрованного текста в обычный текст называется дешифрованием. Это также называется расшифровкой.

Диаграмма, приведенная ниже, показывает иллюстрацию всего процесса криптографии —

Терминология криптографии

Характеристики современной криптографии

Основные характеристики современной криптографии следующие:

  • Он работает на битовых последовательностях.

  • Он использует математические алгоритмы для защиты информации.

  • Это требует от сторон, заинтересованных в безопасном канале связи, добиться конфиденциальности.

Он работает на битовых последовательностях.

Он использует математические алгоритмы для защиты информации.

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

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

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

Другие названия для шифрования двойной силы включают каскадное шифрование или каскадное шифрование.

Уровни двойного шифрования силы

Шифрование двойной силы включает в себя различные уровни шифрования, которые описаны здесь под —

Первый уровень шифрования

Зашифрованный текст генерируется из исходного читаемого сообщения с использованием алгоритмов хеширования и симметричных ключей. Позднее симметричные ключи шифруются с помощью асимметричных ключей. Лучшая иллюстрация для этого шаблона — объединение хеш-кода зашифрованного текста в капсулу. Получатель сначала вычислит дайджест, а затем расшифрует текст, чтобы убедиться, что текст не был изменен между ними.

Второй уровень шифрования

Второй уровень шифрования — это процесс добавления еще одного слоя для шифрования текста с использованием того же или другого алгоритма. Обычно для этого используется 32-битный симметричный длинный пароль.

Третий уровень шифрования

В этом процессе зашифрованная капсула передается через соединение SSL / TLS партнеру по связи.

Следующая диаграмма иллюстрирует процесс двойного шифрования —

Сила Шифрования

Гибридная криптография

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

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

Обзор и установка Python

Python — это язык сценариев с открытым исходным кодом, который является высокоуровневым, интерпретируемым, интерактивным и объектно-ориентированным. Это разработано, чтобы быть очень удобочитаемым. Синтаксис языка Python прост для понимания и часто использует английские ключевые слова.

Особенности языка Python

Python предоставляет следующие основные функции —

Интерпретированный

Python обрабатывается во время выполнения с использованием интерпретатора. Нет необходимости компилировать программу перед выполнением. Это похоже на PERL и PHP.

Объектно-ориентированный

Python следует объектно-ориентированному стилю и шаблонам дизайна. Он включает определение класса с различными функциями, такими как инкапсуляция и полиморфизм.

Ключевые моменты языка Python

Ключевые моменты языка программирования Python следующие:

  • Он включает в себя функциональное и структурное программирование и методы, а также методы объектно-ориентированного программирования.

  • Его можно использовать как язык сценариев или как язык программирования.

  • Включает в себя автоматическую сборку мусора.

  • Он включает в себя динамические типы данных высокого уровня и поддерживает различные проверки динамических типов.

  • Python включает в себя функцию интеграции с C, C ++ и такими языками, как Java.

Он включает в себя функциональное и структурное программирование и методы, а также методы объектно-ориентированного программирования.

Его можно использовать как язык сценариев или как язык программирования.

Включает в себя автоматическую сборку мусора.

Он включает в себя динамические типы данных высокого уровня и поддерживает различные проверки динамических типов.

Python включает в себя функцию интеграции с C, C ++ и такими языками, как Java.

Ссылка для скачивания для языка Python следующая: www.python.org/downloads. Она включает в себя пакеты для различных операционных систем, таких как дистрибутивы Windows, MacOS и Linux.

Python Скачать

Python Strings

Основная декларация строк показана ниже —

str = 'Hello World!'

Списки Python

Списки Python могут быть объявлены как составные типы данных, разделенные запятыми и заключенные в квадратные скобки ([]).

list = [ 'abcd', 786 , 2.23, 'john', 70.2 ]
tinylist = [123, 'john']

Python Tuples

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

tinytuple = (123, 'john')

Словарь Python

Словарь Python — это тип хэш-таблицы. Ключом словаря может быть практически любой тип данных Python, обычно это числа или строки.

tinydict = {'name': 'omkar','code':6734, 'dept': 'sales'}

Криптографические пакеты

Python включает в себя пакет, называемый криптографией, который предоставляет криптографические рецепты и примитивы. Он поддерживает Python 2.7, Python 3.4+ и PyPy 5.3+. Базовая установка пакета криптографии достигается с помощью следующей команды —

pip install cryptography

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

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

Криптография с Python — обратный шифр

В предыдущей главе был дан обзор установки Python на ваш локальный компьютер. В этой главе вы узнаете подробно об обратном шифре и его кодировании.

Алгоритм обратного шифрования

Алгоритм обратного шифрования обладает следующими особенностями —

  • Обратный Шифр ​​использует образец обращения строки простого текста, чтобы преобразовать как текст шифра.

  • Процесс шифрования и дешифрования одинаков.

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

Обратный Шифр ​​использует образец обращения строки простого текста, чтобы преобразовать как текст шифра.

Процесс шифрования и дешифрования одинаков.

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

недостаток

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

недостаток

пример

Рассмотрим пример, где утверждение « Это программа для объяснения обратного шифра» должно быть реализовано с использованием алгоритма обратного шифрования. Следующий код Python использует алгоритм для получения выходных данных.

message = 'This is program to explain reverse cipher.'
translated = '' #cipher text is stored in this variable
i = len(message) - 1

while i >= 0:
   translated = translated + message[i]
   i = i - 1
print(“The cipher text is : “, translated)

Выход

Вы можете увидеть перевернутый текст, то есть вывод, как показано на следующем рисунке —

Выход

объяснение

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

  • Длина обычного текста рассчитывается с использованием цикла for и с помощью номера индекса . Символы хранятся в переведенной текстовой переменной шифра, которая печатается в последней строке.

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

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

Криптография с Питоном — Цезарь Шифр

В последней главе мы имели дело с обратным шифром. В этой главе подробно рассказывается о шифре Цезаря.

Алгоритм Цезаря Шифра

Алгоритм шифра Цезаря обладает следующими особенностями —

  • Caesar Cipher Technique — это простой и легкий метод шифрования.

  • Это простой тип подстановочного шифра.

  • Каждая буква обычного текста заменяется буквой с фиксированным числом позиций вниз по алфавиту.

Caesar Cipher Technique — это простой и легкий метод шифрования.

Это простой тип подстановочного шифра.

Каждая буква обычного текста заменяется буквой с фиксированным числом позиций вниз по алфавиту.

Следующая диаграмма изображает работу реализации алгоритма шифрования Цезаря —

Алгоритм Цезаря Шифра

Программная реализация алгоритма шифрования Цезаря выглядит следующим образом —

def encrypt(text,s):
result = ""
   # transverse the plain text
   for i in range(len(text)):
      char = text[i]
      # Encrypt uppercase characters in plain text
      
      if (char.isupper()):
         result += chr((ord(char) + s-65) % 26 + 65)
      # Encrypt lowercase characters in plain text
      else:
         result += chr((ord(char) + s - 97) % 26 + 97)
      return result
#check the above function
text = "CEASER CIPHER DEMO"
s = 4

print "Plain Text : " + text
print "Shift pattern : " + str(s)
print "Cipher: " + encrypt(text,s)

Выход

Вы можете увидеть шифр Цезаря, то есть вывод, как показано на следующем рисунке —

Цезарь Шифр

объяснение

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

  • Для каждого символа в данном простом тексте преобразуйте данный символ согласно правилу в зависимости от процедуры шифрования и дешифрования текста.

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

Для каждого символа в данном простом тексте преобразуйте данный символ согласно правилу в зависимости от процедуры шифрования и дешифрования текста.

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

Взлом алгоритма Цезаря Шифра

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

Реализация программы для взлома алгоритма шифрования Цезаря выглядит следующим образом —

message = 'GIEWIVrGMTLIVrHIQS' #encrypted message
LETTERS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'

for key in range(len(LETTERS)):
   translated = ''
   for symbol in message:
      if symbol in LETTERS:
         num = LETTERS.find(symbol)
         num = num - key
         if num < 0:
            num = num + len(LETTERS)
         translated = translated + LETTERS[num]
      else:
         translated = translated + symbol
print('Hacking key #%s: %s' % (key, translated))

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

Взлом Цезаря Шифра

Криптография с Python — алгоритм ROT13

До сих пор вы узнали об алгоритмах обратного шифрования и Цезаря. Теперь давайте обсудим алгоритм ROT13 и его реализацию.

Объяснение алгоритма ROT13

Шифр ROT13 относится к сокращенной форме Поворот на 13 мест . Это особый случай Цезаря Шифра, в котором сдвиг всегда равен 13. Каждая буква сдвигается на 13 мест, чтобы зашифровать или расшифровать сообщение.

пример

Следующая диаграмма поясняет процесс алгоритма ROT13 —

ROT13 Алгоритм Процесс

Код программы

Программная реализация алгоритма ROT13 выглядит следующим образом —

from string import maketrans

rot13trans = maketrans('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz', 
   'NOPQRSTUVWXYZABCDEFGHIJKLMnopqrstuvwxyzabcdefghijklm')

# Function to translate plain text
def rot13(text):
   return text.translate(rot13trans)
def main():
   txt = "ROT13 Algorithm"
   print rot13(txt)
	
if __name__ == "__main__":
   main()

Вы можете увидеть выход ROT13, как показано на следующем рисунке —

ROT13

недостаток

Алгоритм ROT13 использует 13 смен. Поэтому очень легко смещать символы в обратном порядке, чтобы расшифровать зашифрованный текст.

Анализ алгоритма ROT13

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

Шифр транспонирования

Транспозиционный шифр — это криптографический алгоритм, в котором порядок алфавитов в открытом тексте перестраивается для формирования зашифрованного текста. В этот процесс фактические алфавиты простого текста не включаются.

пример

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

Рассмотрим простой текст hello world , и давайте применим технику простого столбчатого преобразования, как показано ниже

Колонное Транспонирование

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

Код

Следующий программный код демонстрирует базовую реализацию метода столбчатой ​​транспозиции —

def split_len(seq, length):
   return [seq[i:i + length] for i in range(0, len(seq), length)]
def encode(key, plaintext):
   order = {
      int(val): num for num, val in enumerate(key)
   }
ciphertext = ''

for index in sorted(order.keys()):
   for part in split_len(plaintext, len(key)):
      try:ciphertext += part[order[index]]
         except IndexError:
            continue
   return ciphertext
print(encode('3214', 'HELLO'))

объяснение

  • Используя функцию split_len (), мы можем разделить символы простого текста, которые могут быть размещены в столбчатом или строчном формате.

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

Используя функцию split_len (), мы можем разделить символы простого текста, которые могут быть размещены в столбчатом или строчном формате.

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

Выход

Программный код для базовой реализации метода столбчатой ​​транспозиции дает следующий результат:

Техника транспонирования столбцов

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

Шифрование транспонированного шифра

В предыдущей главе мы узнали о шифре транспонирования. В этой главе давайте обсудим его шифрование.

Pyperclip

Основное использование плагина pyperclip в языке программирования Python — выполнение кроссплатформенного модуля для копирования и вставки текста в буфер обмена. Вы можете установить модуль Python Pyperclip с помощью команды, как показано

pip install pyperclip

Если требование уже существует в системе, вы можете увидеть следующий вывод:

Pyperclip

Код

Код Python для шифрования шифра транспонирования, в котором Pyperclip является основным модулем, показан ниже:

import pyperclip
def main():
   myMessage = 'Transposition Cipher'
   myKey = 10
   ciphertext = encryptMessage(myKey, myMessage)
   
   print("Cipher Text is")
   print(ciphertext + '|')
   pyperclip.copy(ciphertext)

def encryptMessage(key, message):
   ciphertext = [''] * key
   
   for col in range(key):
      position = col
      while position < len(message):
         ciphertext[col] += message[position]
			position += key
      return ''.join(ciphertext) #Cipher text
if __name__ == '__main__':
   main()

Выход

Программный код для шифрования транспонированного шифра, в котором pyperclip является основным модулем, дает следующий вывод:

Шифрование Транспонирование

объяснение

  • Функция main () вызывает метод encryptMessage (), который включает в себя процедуру разделения символов с помощью функции len и их итерации в столбчатом формате.

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

Функция main () вызывает метод encryptMessage (), который включает в себя процедуру разделения символов с помощью функции len и их итерации в столбчатом формате.

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

Расшифровка транспозиционного шифра

В этой главе вы узнаете, как расшифровывать шифр транспонирования.

Код

Обратите внимание на следующий код для лучшего понимания расшифровки транспозиционного шифра. Текст шифра для сообщения Transposition Cipher с ключом 6 выбирается как Toners raiCntisippoh.

import math, pyperclip
def main():
   myMessage= 'Toners raiCntisippoh'
   myKey = 6
   plaintext = decryptMessage(myKey, myMessage)
   
   print("The plain text is")
   print('Transposition Cipher')

def decryptMessage(key, message):
   numOfColumns = math.ceil(len(message) / key)
   numOfRows = key
   numOfShadedBoxes = (numOfColumns * numOfRows) - len(message)
   plaintext = float('') * numOfColumns
   col = 0
   row = 0
   
   for symbol in message:
      plaintext[col] += symbol
      col += 1
      if (col == numOfColumns) or (col == numOfColumns - 1 and row >= numOfRows - numOfShadedBoxes):
         col = 0 row += 1 return ''.join(plaintext)
if __name__ == '__main__':
   main()

объяснение

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

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

for symbol in message:
   plaintext[col] += symbol
   col += 1
   
   if (col == numOfColumns) or (col == numOfColumns - 1 and row >= numOfRows - numOfShadedBoxes):
   col = 0
   row += 1
return ''.join(plaintext)

Выход

Программный код для расшифровки шифра транспонирования дает следующий вывод —

Расшифровка транспонирования

Шифрование файлов

В Python можно зашифровать и расшифровать файлы перед передачей в канал связи. Для этого вам нужно будет использовать плагин PyCrypto . Вы можете установить этот плагин с помощью команды, приведенной ниже.

pip install pycrypto

PyCrypto

Код

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

# =================Other Configuration================
# Usages :
usage = "usage: %prog [options] "
# Version
Version="%prog 0.0.1"
# ====================================================
# Import Modules
import optparse, sys,os
from toolkit import processor as ps
def main():
   parser = optparse.OptionParser(usage = usage,version = Version)
   parser.add_option(
      '-i','--input',type = 'string',dest = 'inputfile',
      help = "File Input Path For Encryption", default = None)
   
   parser.add_option(
      '-o','--output',type = "string",dest = 'outputfile',
      help = "File Output Path For Saving Encrypter Cipher",default = ".")
	
   parser.add_option(
      '-p','--password',type = "string",dest = 'password',
      help = "Provide Password For Encrypting File",default = None)
	
   parser.add_option(
      '-p','--password',type = "string",dest = 'password',
      help = "Provide Password For Encrypting File",default = None)
	
   (options, args)= parser.parse_args()
	
   # Input Conditions Checkings
   if not options.inputfile or not os.path.isfile(options.inputfile):
      print " [Error] Please Specify Input File Path"
      exit(0)
   if not options.outputfile or not os.path.isdir(options.outputfile):
      print " [Error] Please Specify Output Path"
      exit(0)
   if not options.password:
      print " [Error] No Password Input"
      exit(0)
   inputfile = options.inputfile

   outputfile = os.path.join(
      options.outputfile,os.path.basename(options.inputfile).split('.')[0]+'.ssb')
   password = options.password
   base = os.path.basename(inputfile).split('.')[1]
   work = "E"

   ps.FileCipher(inputfile,outputfile,password,work)
   return

   if __name__ == '__main__':
   main()

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

python pyfilecipher-encrypt.py -i file_path_for_encryption -o output_path -p password

Выход

Вы можете наблюдать следующий вывод при выполнении кода, приведенного выше —

Процесс шифрования

объяснение

Пароли генерируются с использованием алгоритма хеширования MD5, а значения хранятся в просто безопасных файлах резервных копий в системе Windows, которые включают значения, как показано ниже:

объяснение

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

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

Код

Ниже приведен пример кода для расшифровки файлов в криптографии с использованием Python:

#!/usr/bin/python
# ---------------- READ ME ---------------------------------------------
# This Script is Created Only For Practise And Educational Purpose Only
# This Script Is Created For http://bitforestinfo.blogspot.in
# This Script is Written By
#
#
##################################################
######## Please Don't Remove Author Name #########
############### Thanks ###########################
##################################################
#
#
# =================Other Configuration================
# Usages :
usage = "usage: %prog [options] "
# Version
Version="%prog 0.0.1"
# ====================================================
# Import Modules
import optparse, sys,os
from toolkit import processor as ps
def main():
   parser = optparse.OptionParser(usage = usage,version = Version)
   parser.add_option(
      '-i','--input',type = 'string',dest = 'inputfile',
      help = "File Input Path For Encryption", default = None)
   
   parser.add_option(
      '-o','--output',type = "string",dest = 'outputfile',
      help = "File Output Path For Saving Encrypter Cipher",default = ".")
   
   parser.add_option(
      '-p','--password',type = "string",dest = 'password',
      help = "Provide Password For Encrypting File",default = None)
      (options, args) =  parser.parse_args()
      # Input Conditions Checkings
      if not options.inputfile or not os.path.isfile(options.inputfile):
         print " [Error] Please Specify Input File Path"
         exit(0)
      if not options.outputfile or not os.path.isdir(options.outputfile):
         print " [Error] Please Specify Output Path"
         exit(0)
      if not options.password:
         print " [Error] No
         exit(0)
      inputfile = options.inputfile
      outputfile = options.outputfile
      password = options.password
      work = "D"
      ps.FileCipher(inputfile,outputfile,password,work)
      return
if __name__ == '__main__':
   main()

Вы можете использовать следующую команду для выполнения приведенного выше кода —

python pyfilecipher-decrypt.py -i encrypted_file_path -p password

Выход

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

Дешифровка

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

Base64 кодирование и декодирование

Кодировка Base64 преобразует двоичные данные в текстовый формат, который передается по каналу связи, где пользователь может безопасно обрабатывать текст. Base64 также называется электронной почтой с улучшенной конфиденциальностью (PEM) и в основном используется в процессе шифрования электронной почты.

Python включает в себя модуль под названием BASE64, который включает в себя две основные функции, как указано ниже —

  • base64.decode (input, output) — декодирует указанный параметр входного значения и сохраняет декодированный вывод как объект.

  • Base64.encode (вход, выход) — кодирует указанный параметр входного значения и сохраняет декодированный вывод как объект.

base64.decode (input, output) — декодирует указанный параметр входного значения и сохраняет декодированный вывод как объект.

Base64.encode (вход, выход) — кодирует указанный параметр входного значения и сохраняет декодированный вывод как объект.

Программа для кодирования

Вы можете использовать следующий фрагмент кода для выполнения кодирования base64 —

import base64
encoded_data = base64.b64encode("Encode this text")

print("Encoded text with base 64 is")
print(encoded_data)

Выход

Код для кодирования base64 дает следующий вывод —

Base64

Программа для декодирования

Вы можете использовать следующий фрагмент кода для выполнения декодирования base64 —

import base64
decoded_data = base64.b64decode("RW5jb2RlIHRoaXMgdGV4dA==")

print("decoded text is ")
print(decoded_data)

Выход

Код для декодирования base64 дает следующий вывод —

Base64 декодирование

Разница между ASCII и base64

Вы можете наблюдать следующие различия при работе с ASCII и base64 для кодирования данных:

  • Когда вы кодируете текст в ASCII, вы начинаете с текстовой строки и преобразуете ее в последовательность байтов.

  • Когда вы кодируете данные в Base64, вы начинаете с последовательности байтов и преобразуете ее в текстовую строку.

Когда вы кодируете текст в ASCII, вы начинаете с текстовой строки и преобразуете ее в последовательность байтов.

Когда вы кодируете данные в Base64, вы начинаете с последовательности байтов и преобразуете ее в текстовую строку.

недостаток

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

Криптография с Python — процесс XOR

В этой главе давайте разберемся с процессом XOR и его кодированием на Python.

Алгоритм

Алгоритм шифрования и дешифрования XOR преобразует простой текст в формат байтов ASCII и использует процедуру XOR для преобразования его в указанный байт. Он предлагает следующие преимущества для своих пользователей —

  • Быстрое вычисление
  • Нет разницы отмечены в левой и правой части
  • Легко понять и проанализировать

Код

Вы можете использовать следующий фрагмент кода для выполнения процесса XOR —

def xor_crypt_string(data, key = 'awesomepassword', encode = False, decode = False):
   from itertools import izip, cycle
   import base64
   
   if decode:
      data = base64.decodestring(data)
   xored = ''.join(chr(ord(x) ^ ord(y)) for (x,y) in izip(data, cycle(key)))
   
   if encode:
      return base64.encodestring(xored).strip()
   return xored
secret_data = "XOR procedure"

print("The cipher text is")
print xor_crypt_string(secret_data, encode = True)
print("The plain text fetched")
print xor_crypt_string(xor_crypt_string(secret_data, encode = True), decode = True)

Выход

Код для процесса XOR дает следующий вывод —

исключающее

объяснение

  • Функция xor_crypt_string () включает в себя параметр для указания режима кодирования и декодирования, а также строковое значение.

  • Основные функции выполняются с модулями base64, которые следуют процедуре / операции XOR для шифрования или дешифрования обычного текста / зашифрованного текста.

Функция xor_crypt_string () включает в себя параметр для указания режима кодирования и декодирования, а также строковое значение.

Основные функции выполняются с модулями base64, которые следуют процедуре / операции XOR для шифрования или дешифрования обычного текста / зашифрованного текста.

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

Мультипликативный Шифр

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

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

Ассоциированные номера

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

(Alphabet Number * key)mod(total number of alphabets)

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

Зашифрованное письмо

Основная функция модуляции мультипликативного шифра в Python следующая:

def unshift(key, ch):
   offset = ord(ch) - ASC_A
   return chr(((key[0] * (offset + key[1])) % WIDTH) + ASC_A)

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

Криптография с Python — Аффинный Шифр

Affine Cipher представляет собой комбинацию алгоритма Multiplicative Cipher и Caesar Cipher. Основная реализация аффинного шифра, как показано на рисунке ниже —

базовая реализация аффинного шифра

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

Код

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

class Affine(object):
   DIE = 128
   KEY = (7, 3, 55)
   def __init__(self):
      pass
   def encryptChar(self, char):
      K1, K2, kI = self.KEY
      return chr((K1 * ord(char) + K2) % self.DIE)
		
   def encrypt(self, string):
      return "".join(map(self.encryptChar, string))
   
   def decryptChar(self, char):
      K1, K2, KI = self.KEY
      return chr(KI * (ord(char) - K2) % self.DIE)
   
   def decrypt(self, string):
      return "".join(map(self.decryptChar, string))
		affine = Affine()
print affine.encrypt('Affine Cipher')
print affine.decrypt('*18?FMT')

Выход

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

аффинных

Выходные данные отображают зашифрованное сообщение для простого текстового сообщения Affine Cipher и расшифрованное сообщение для сообщения, отправляемого в качестве ввода abcdefg.

Взлом моноалфавитного шифра

В этой главе вы узнаете о моноалфавитном шифре и его взломе с использованием Python.

Моноалфавитный шифр

Monoalphabetic шифр использует фиксированную замену для шифрования всего сообщения. Моноалфавитный шифр, использующий словарь Python с объектами JSON, показан здесь —

monoalpha_cipher = {
   'a': 'm',
   'b': 'n',
   'c': 'b',
   'd': 'v',
   'e': 'c',
   'f': 'x',
   'g': 'z',
   'h': 'a',
   'i': 's',
   'j': 'd',
   'k': 'f',
   'l': 'g',
   'm': 'h',
   'n': 'j',
   'o': 'k',
   'p': 'l',
   'q': 'p',
   'r': 'o',
   's': 'i',
   't': 'u',
   'u': 'y',
   'v': 't',
   'w': 'r',
   'x': 'e',
   'y': 'w',
   'z': 'q',
	' ': ' ',
}

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

from string import letters, digits
from random import shuffle

def random_monoalpha_cipher(pool = None):
   if pool is None:
      pool = letters + digits
   original_pool = list(pool)
   shuffled_pool = list(pool)
   shuffle(shuffled_pool)
   return dict(zip(original_pool, shuffled_pool))

def inverse_monoalpha_cipher(monoalpha_cipher):
   inverse_monoalpha = {}
   for key, value in monoalpha_cipher.iteritems():
      inverse_monoalpha[value] = key
   return inverse_monoalpha

def encrypt_with_monoalpha(message, monoalpha_cipher):
   encrypted_message = []
   for letter in message:
      encrypted_message.append(monoalpha_cipher.get(letter, letter))
   return ''.join(encrypted_message)

def decrypt_with_monoalpha(encrypted_message, monoalpha_cipher):
   return encrypt_with_monoalpha(
      encrypted_message,
      inverse_monoalpha_cipher(monoalpha_cipher)
   )

Этот файл вызывается позже для реализации процесса шифрования и дешифрования моноалфавитного шифра, который упоминается ниже:

import monoalphabeticCipher as mc

cipher = mc.random_monoalpha_cipher()
print(cipher)
encrypted = mc.encrypt_with_monoalpha('Hello all you hackers out there!', cipher)
decrypted = mc.decrypt_with_monoalpha('sXGGt SGG Nt0 HSrLXFC t0U UHXFX!', cipher)

print(encrypted)
print(decrypted)

Выход

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

моноалфавитных

Таким образом, вы можете взломать моноалфавитный шифр с заданной парой ключ-значение, который превращает текст шифра в реальный простой текст.

Простой Подстановочный Шифр

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

пример

Ключи для простого подстановочного шифра обычно состоят из 26 букв. Пример ключа —

plain alphabet : abcdefghijklmnopqrstuvwxyz
cipher alphabet: phqgiumeaylnofdxjkrcvstzwb

Пример шифрования с использованием вышеуказанного ключа:

plaintext : defend the east wall of the castle
ciphertext: giuifg cei iprc tpnn du cei qprcni

В следующем коде показана программа для реализации простого шифра замещения —

import random, sys

LETTERS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
def main():
   message = ''
   if len(sys.argv) > 1:
      with open(sys.argv[1], 'r') as f:
         message = f.read()
   else:
      message = raw_input("Enter your message: ")
   mode = raw_input("E for Encrypt, D for Decrypt: ")
   key = ''
   
   while checkKey(key) is False:
      key = raw_input("Enter 26 ALPHA key (leave blank for random key): ")
      if key == '':
         key = getRandomKey()
      if checkKey(key) is False:
		print('There is an error in the key or symbol set.')
   translated = translateMessage(message, key, mode)
   print('Using key: %s' % (key))
   
   if len(sys.argv) > 1:
      fileOut = 'enc.' + sys.argv[1]
      with open(fileOut, 'w') as f:
         f.write(translated)
      print('Success! File written to: %s' % (fileOut))
   else: print('Result: ' + translated)

# Store the key into list, sort it, convert back, compare to alphabet.
def checkKey(key):
   keyString = ''.join(sorted(list(key)))
   return keyString == LETTERS
def translateMessage(message, key, mode):
   translated = ''
   charsA = LETTERS
   charsB = key
   
   # If decrypt mode is detected, swap A and B
   if mode == 'D':
      charsA, charsB = charsB, charsA
   for symbol in message:
      if symbol.upper() in charsA:
         symIndex = charsA.find(symbol.upper())
         if symbol.isupper():
            translated += charsB[symIndex].upper()
         else:
            translated += charsB[symIndex].lower()
				else:
               translated += symbol
         return translated
def getRandomKey():
   randomList = list(LETTERS)
   random.shuffle(randomList)
   return ''.join(randomList)
if __name__ == '__main__':
   main()

Выход

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

Простая замена

Тестирование простого подстановочного шифра

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

import random, string, substitution
def main():
   for i in range(1000):
      key = substitution.getRandomKey()
      message = random_string()
      print('Test %s: String: "%s.."' % (i + 1, message[:50]))
      print("Key: " + key)
      encrypted = substitution.translateMessage(message, key, 'E')
      decrypted = substitution.translateMessage(encrypted, key, 'D')
      
      if decrypted != message:
         print('ERROR: Decrypted: "%s" Key: %s' % (decrypted, key))
         sys.exit()
      print('Substutition test passed!')

def random_string(size = 5000, chars = string.ascii_letters + string.digits):
   return ''.join(random.choice(chars) for _ in range(size))
if __name__ == '__main__':
   main()

Выход

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

Струны

После того, как тест успешно завершен, мы можем наблюдать выходное сообщение Замененный тест пройден !.

подмена

Таким образом, вы можете взломать шифр замещения в систематической манере.

Расшифровка простого подстановочного шифра

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

Код

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

import random
chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' + \
   'abcdefghijklmnopqrstuvwxyz' + \
   '0123456789' + \
   ':.;,?!@#$%&()+=-*/_<> []{}`~^"\'\\'

def generate_key():
   """Generate an key for our cipher"""
   shuffled = sorted(chars, key=lambda k: random.random())
   return dict(zip(chars, shuffled))

def encrypt(key, plaintext):
   """Encrypt the string and return the ciphertext"""
   return ''.join(key[l] for l in plaintext)

def decrypt(key, ciphertext):
   """Decrypt the string and return the plaintext"""
   flipped = {v: k for k, v in key.items()}
   return ''.join(flipped[l] for l in ciphertext)

def show_result(plaintext):
   """Generate a resulting cipher with elements shown"""
   key = generate_key()
   encrypted = encrypt(key, plaintext)
   decrypted = decrypt(key, encrypted)
   
   print 'Key: %s' % key
	print 'Plaintext: %s' % plaintext
   print 'Encrypted: %s' % encrypted
   print 'Decrypted: %s' % decrypted
show_result('Hello World. This is demo of substitution cipher')

Выход

Приведенный выше код дает вам вывод, как показано здесь —

Реализация

Модули криптографии Python

В этой главе вы узнаете подробно о различных модулях криптографии в Python.

Модуль криптографии

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

pip install cryptography

PIP Установить

Код

Вы можете использовать следующий код для реализации модуля криптографии —

from cryptography.fernet import Fernet
key = Fernet.generate_key()
cipher_suite = Fernet(key)
cipher_text = cipher_suite.encrypt("This example is used to demonstrate cryptography module")
plain_text = cipher_suite.decrypt(cipher_text)

Выход

Приведенный выше код дает следующий вывод:

Аутентификация

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

import uuid
import hashlib

def hash_password(password):
   # uuid is used to generate a random number of the specified password
   salt = uuid.uuid4().hex
   return hashlib.sha256(salt.encode() + password.encode()).hexdigest() + ':' + salt

def check_password(hashed_password, user_password):
   password, salt = hashed_password.split(':')
   return password == hashlib.sha256(salt.encode() + user_password.encode()).hexdigest()

new_pass = input('Please enter a password: ')
hashed_password = hash_password(new_pass)
print('The string to store in the db is: ' + hashed_password)
old_pass = input('Now please enter the password again to check: ')

if check_password(hashed_password, old_pass):
   print('You entered the right password')
else:
   print('Passwords do not match')

Выход

Сценарий 1. Если вы ввели правильный пароль, вы можете найти следующий вывод:

Правильный пароль

Сценарий 2 — Если мы введем неправильный пароль, вы можете найти следующий вывод —

Неправильный пароль

объяснение

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

Понимание Vignere Cipher

Vignere Cipher включает в себя алгоритм шифрования Цезаря, используемый для шифрования и дешифрования. Vignere Cipher работает аналогично алгоритму Caesar Cipher только с одним основным отличием: Caesar Cipher включает алгоритм односимвольного сдвига, тогда как Vignere Cipher включает ключ со множественным сдвигом алфавитов.

Математическое уравнение

Для шифрования математическое уравнение выглядит следующим образом:

$$ E_ {k} \ left (M {_ {i {}}} \ right) = \ left (M_ {i} + K_ {i} \ right) \; \; \; мод \; \; 26 $$

Для расшифровки математическое уравнение выглядит следующим образом:

$$ D_ {k} \ left (C {_ {i {}}} \ right) = \ left (C_ {i} -K_ {i} \ right) \; \; \; мод \; \; 26 $$

Шифр Vignere использует более одного набора замен, и, следовательно, его также называют полиальфабетическим шифром . Vignere Cipher будет использовать буквенный ключ вместо числового представления ключа: буква A будет использоваться для ключа 0, буква B для ключа 1 и так далее. Номера букв до и после процесса шифрования показаны ниже —

полиалфабетический шифр

Возможная комбинация количества возможных ключей на основе длины ключа Vignere дается следующим образом, что дает результат того, насколько безопасен алгоритм Vignere Cipher —

Vignere Cipher

Vignere Tableau

Таблица, используемая для шифра Vignere, показана ниже:

Vignere Tableau

Внедрение Vignere Cipher

В этой главе давайте разберемся, как реализовать шифр Vignere. Рассмотрим текст. Это базовая реализация Vignere Cipher, которая должна быть закодирована, а ключ — это PIZZA.

Код

Вы можете использовать следующий код для реализации шифра Vignere в Python —

import pyperclip

LETTERS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
def main():
   myMessage = "This is basic implementation of Vignere Cipher"
   myKey = 'PIZZA'
   myMode = 'encrypt'
   
   if myMode == 'encrypt':
      translated = encryptMessage(myKey, myMessage)
   elif myMode == 'decrypt':
      translated = decryptMessage(myKey, myMessage)
   
   print('%sed message:' % (myMode.title()))
   print(translated)
   print()
def encryptMessage(key, message):
   return translateMessage(key, message, 'encrypt')
def decryptMessage(key, message):
   return translateMessage(key, message, 'decrypt')
def translateMessage(key, message, mode):
   translated = [] # stores the encrypted/decrypted message string
   keyIndex = 0
   key = key.upper()
   
   for symbol in message:
      num = LETTERS.find(symbol.upper())
      if num != -1:
         if mode == 'encrypt':
            num += LETTERS.find(key[keyIndex])
				elif mode == 'decrypt':
               num -= LETTERS.find(key[keyIndex])
            num %= len(LETTERS)
            
            if symbol.isupper():
               translated.append(LETTERS[num])
            elif symbol.islower():
               translated.append(LETTERS[num].lower())
            keyIndex += 1
            
            if keyIndex == len(key):
               keyIndex = 0
         else:
            translated.append(symbol)
      return ''.join(translated)
if __name__ == '__main__':
   main()

Выход

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

безопасный режим шифрования

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

Одноразовый шифровальный блок

Одноразовый блочный шифр — это тип шифра Vignere, который включает в себя следующие функции:

  • Это небьющийся шифр.

  • Ключ точно такой же, как длина зашифрованного сообщения.

  • Ключ состоит из случайных символов.

  • Как следует из названия, ключ используется только один раз и никогда больше не используется для шифрования любого другого сообщения.

Это небьющийся шифр.

Ключ точно такой же, как длина зашифрованного сообщения.

Ключ состоит из случайных символов.

Как следует из названия, ключ используется только один раз и никогда больше не используется для шифрования любого другого сообщения.

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

Почему это нерушимо?

Ключ неразрывен благодаря следующим функциям:

  • Ключ такой же длины, как и данное сообщение.

  • Ключ действительно случайный и специально сгенерированный.

  • Ключ и простой текст рассчитываются по модулю 26.10.2.

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

  • Должно быть две копии ключа: одна с отправителем, другая с получателем.

Ключ такой же длины, как и данное сообщение.

Ключ действительно случайный и специально сгенерированный.

Ключ и простой текст рассчитываются по модулю 26.10.2.

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

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

шифрование

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

OTP

Дешифрирование

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

Внедрение One Time Pad Cipher

Python включает в себя хакерский модуль реализации для реализации одноразового шифрования. Имя пакета называется One-Time-Pad, которое включает в себя инструмент шифрования командной строки, который использует механизм шифрования, аналогичный алгоритму шифрования одноразовых клавиш.

Монтаж

Вы можете использовать следующую команду для установки этого модуля —

pip install onetimepad

Если вы хотите использовать его из командной строки, выполните следующую команду —

onetimepad

PIP

Код

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

import onetimepad

cipher = onetimepad.encrypt('One Time Cipher', 'random')
print("Cipher text is ")
print(cipher)
print("Plain text is ")
msg = onetimepad.decrypt(cipher, 'random')

print(msg)

Выход

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

PIP-выход

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

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

Симметричная и асимметричная криптография

В этой главе давайте обсудим подробно о симметричной и асимметричной криптографии.

Симметричная криптография

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

  • Это проще и быстрее.
  • Обе стороны обмениваются ключом безопасным способом.

недостаток

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

Стандарт шифрования данных (DES)

Наиболее популярным алгоритмом симметричного ключа является стандарт шифрования данных (DES), а Python включает пакет, включающий логику алгоритма DES.

Монтаж

Команда для установки пакета pyDES DES в Python —

pip install pyDES

pyDES

Простая программная реализация алгоритма DES заключается в следующем —

import pyDes

data = "DES Algorithm Implementation"
k = pyDes.des("DESCRYPT", pyDes.CBC, "\0\0\0\0\0\0\0\0", pad=None, padmode=pyDes.PAD_PKCS5)
d = k.encrypt(data)

print "Encrypted: %r" % d
print "Decrypted: %r" % k.decrypt(d)
assert k.decrypt(d) == data

Он вызывает переменную padmode, которая выбирает все пакеты согласно реализации алгоритма DES и выполняет шифрование и дешифрование указанным способом.

Выход

Вы можете увидеть следующий вывод в результате кода, приведенного выше —

Алгоритм DES

Асимметричная криптография

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

недостаток

  • Благодаря своей длине ключа он обеспечивает более низкую скорость шифрования.
  • Управление ключами имеет решающее значение.

Следующий программный код на Python иллюстрирует работу асимметричной криптографии с использованием алгоритма RSA и его реализацию —

from Crypto import Random
from Crypto.PublicKey import RSA
import base64

def generate_keys():
   # key length must be a multiple of 256 and >= 1024
   modulus_length = 256*4
   privatekey = RSA.generate(modulus_length, Random.new().read)
   publickey = privatekey.publickey()
   return privatekey, publickey

def encrypt_message(a_message , publickey):
   encrypted_msg = publickey.encrypt(a_message, 32)[0]
   encoded_encrypted_msg = base64.b64encode(encrypted_msg)
   return encoded_encrypted_msg

def decrypt_message(encoded_encrypted_msg, privatekey):
   decoded_encrypted_msg = base64.b64decode(encoded_encrypted_msg)
   decoded_decrypted_msg = privatekey.decrypt(decoded_encrypted_msg)
   return decoded_decrypted_msg

a_message = "This is the illustration of RSA algorithm of asymmetric cryptography"
privatekey , publickey = generate_keys()
encrypted_msg = encrypt_message(a_message , publickey)
decrypted_msg = decrypt_message(encrypted_msg, privatekey)

print "%s - (%d)" % (privatekey.exportKey() , len(privatekey.exportKey()))
print "%s - (%d)" % (publickey.exportKey() , len(publickey.exportKey()))
print " Original content: %s - (%d)" % (a_message, len(a_message))
print "Encrypted message: %s - (%d)" % (encrypted_msg, len(encrypted_msg))
print "Decrypted message: %s - (%d)" % (decrypted_msg, len(decrypted_msg))

Выход

Вы можете найти следующий вывод при выполнении приведенного выше кода —

RSA

Понимание алгоритма RSA

Алгоритм RSA является методом шифрования с открытым ключом и считается наиболее безопасным способом шифрования. Он был изобретен Ривестом, Шамиром и Адлеманом в 1978 году и, следовательно, назвал алгоритм RSA .

Алгоритм

Алгоритм RSA имеет следующие особенности —

  • Алгоритм RSA является популярным возведением в степень в конечном поле по целым числам, включая простые числа.

  • Целые числа, используемые этим методом, достаточно большие, что затрудняет их решение.

  • В этом алгоритме есть два набора ключей: закрытый ключ и открытый ключ.

Алгоритм RSA является популярным возведением в степень в конечном поле по целым числам, включая простые числа.

Целые числа, используемые этим методом, достаточно большие, что затрудняет их решение.

В этом алгоритме есть два набора ключей: закрытый ключ и открытый ключ.

Вам нужно будет выполнить следующие шаги, чтобы работать над алгоритмом RSA —

Шаг 1: Генерация модуля RSA

Начальная процедура начинается с выбора двух простых чисел, а именно p и q, а затем вычисляется их произведение N, как показано ниже:

N=p*q

Здесь пусть N будет указанным большим числом.

Шаг 2: Производное число (е)

Рассмотрим число e как производное число, которое должно быть больше 1 и меньше, чем (p-1) и (q-1). Основным условием будет то, что не должно быть общих множителей (p-1) и (q-1), кроме 1

Шаг 3: Открытый ключ

Указанная пара чисел n и e образует открытый ключ RSA, и он становится открытым.

Шаг 4: Закрытый ключ

Закрытый ключ d рассчитывается из чисел p, q и e. Математическое соотношение между числами выглядит следующим образом:

ed = 1 mod (p-1) (q-1)

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

Формула шифрования

Рассмотрим отправителя, который отправляет текстовое сообщение тому, чей открытый ключ (n, e). Чтобы зашифровать текстовое сообщение в данном сценарии, используйте следующий синтаксис —

C = Pe mod n

Формула расшифровки

Процесс дешифрования очень прост и включает в себя аналитику для расчета в систематическом подходе. Учитывая, что получатель C имеет закрытый ключ d , модуль результата будет вычислен как —

Plaintext = Cd mod n

Создание ключей RSA

В этой главе мы сосредоточимся на пошаговой реализации алгоритма RSA с использованием Python.

Генерация ключей RSA

Следующие шаги участвуют в создании ключей RSA —

  • Создайте два больших простых числа, а именно p и q . Произведение этих чисел будет называться n , где n = p * q

  • Генерация случайного числа, которое является относительно простым с (p-1) и (q-1). Пусть число будет называться e .

  • Рассчитать модульную обратную величину e. Вычисленный обратный будет называться d .

Создайте два больших простых числа, а именно p и q . Произведение этих чисел будет называться n , где n = p * q

Генерация случайного числа, которое является относительно простым с (p-1) и (q-1). Пусть число будет называться e .

Рассчитать модульную обратную величину e. Вычисленный обратный будет называться d .

Алгоритмы генерации ключей RSA

Нам нужны два основных алгоритма генерации ключей RSA с использованием модуля Python — модуль Cryptomath и модуль Рабина Миллера .

Модуль Криптомата

Исходный код модуля cryptomath, который следует всем основным реализациям алгоритма RSA, выглядит следующим образом:

def gcd(a, b):
   while a != 0:
      a, b = b % a, a
   return b

def findModInverse(a, m):
   if gcd(a, m) != 1:
      return None
   u1, u2, u3 = 1, 0, a
   v1, v2, v3 = 0, 1, m
   
   while v3 != 0:
      q = u3 // v3
         v1, v2, v3, u1, u2, u3 = (u1 - q * v1), (u2 - q * v2), (u3 - q * v3), v1, v2, v3
   return u1 % m

Модуль РабинМиллер

Исходный код модуля RabinMiller, который следует всем основным реализациям алгоритма RSA, выглядит следующим образом:

import random
def rabinMiller(num):
   s = num - 1
   t = 0
   
   while s % 2 == 0:
      s = s // 2
      t += 1
   for trials in range(5):
      a = random.randrange(2, num - 1)
      v = pow(a, s, num)
      if v != 1:
         i = 0
         while v != (num - 1):
            if i == t - 1:
               return False
            else:
               i = i + 1
               v = (v ** 2) % num
      return True
def isPrime(num):
   if (num 7< 2):
      return False
   lowPrimes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 
   67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 
   157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 
   251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313,317, 331, 337, 347, 349, 
   353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 
   457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 
   571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 
   673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 
   797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 
   911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997]
	
   if num in lowPrimes:
      return True
   for prime in lowPrimes:
      if (num % prime == 0):
         return False
   return rabinMiller(num)
def generateLargePrime(keysize = 1024):
   while True:
      num = random.randrange(2**(keysize-1), 2**(keysize))
      if isPrime(num):
         return num

Полный код для генерации ключей RSA выглядит следующим образом:

import random, sys, os, rabinMiller, cryptomath

def main():
   makeKeyFiles('RSA_demo', 1024)

def generateKey(keySize):
   # Step 1: Create two prime numbers, p and q. Calculate n = p * q.
   print('Generating p prime...')
   p = rabinMiller.generateLargePrime(keySize)
   print('Generating q prime...')
   q = rabinMiller.generateLargePrime(keySize)
   n = p * q
	
   # Step 2: Create a number e that is relatively prime to (p-1)*(q-1).
   print('Generating e that is relatively prime to (p-1)*(q-1)...')
   while True:
      e = random.randrange(2 ** (keySize - 1), 2 ** (keySize))
      if cryptomath.gcd(e, (p - 1) * (q - 1)) == 1:
         break
   
   # Step 3: Calculate d, the mod inverse of e.
   print('Calculating d that is mod inverse of e...')
   d = cryptomath.findModInverse(e, (p - 1) * (q - 1))
   publicKey = (n, e)
   privateKey = (n, d)
   print('Public key:', publicKey)
   print('Private key:', privateKey)
   return (publicKey, privateKey)

def makeKeyFiles(name, keySize):
   # Creates two files 'x_pubkey.txt' and 'x_privkey.txt' 
      (where x is the value in name) with the the n,e and d,e integers written in them,
   # delimited by a comma.
   if os.path.exists('%s_pubkey.txt' % (name)) or os.path.exists('%s_privkey.txt' % (name)):
      sys.exit('WARNING: The file %s_pubkey.txt or %s_privkey.txt already exists! Use a different name or delete these files and re-run this program.' % (name, name))
   publicKey, privateKey = generateKey(keySize)
   print()
   print('The public key is a %s and a %s digit number.' % (len(str(publicKey[0])), len(str(publicKey[1])))) 
   print('Writing public key to file %s_pubkey.txt...' % (name))
   
   fo = open('%s_pubkey.txt' % (name), 'w')
	fo.write('%s,%s,%s' % (keySize, publicKey[0], publicKey[1]))
   fo.close()
   print()
   print('The private key is a %s and a %s digit number.' % (len(str(publicKey[0])), len(str(publicKey[1]))))
   print('Writing private key to file %s_privkey.txt...' % (name))
   
   fo = open('%s_privkey.txt' % (name), 'w')
   fo.write('%s,%s,%s' % (keySize, privateKey[0], privateKey[1]))
   fo.close()
# If makeRsaKeys.py is run (instead of imported as a module) call
# the main() function.
if __name__ == '__main__':
   main()

Выход

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

ОткрытыйКлюч

Шифрование RSA

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

Модули, включенные в алгоритм шифрования, следующие:

from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP
from Crypto.Signature import PKCS1_v1_5
from Crypto.Hash import SHA512, SHA384, SHA256, SHA, MD5
from Crypto import Random
from base64 import b64encode, b64decode
hash = "SHA-256"

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

def newkeys(keysize):
   random_generator = Random.new().read
   key = RSA.generate(keysize, random_generator)
   private, public = key, key.publickey()
   return public, private
def importKey(externKey):
   return RSA.importKey(externKey)

Для шифрования используется следующая функция, которая следует алгоритму RSA —

def encrypt(message, pub_key):
   cipher = PKCS1_OAEP.new(pub_key)
   return cipher.encrypt(message)

Два параметра являются обязательными: message и pub_key, который ссылается на открытый ключ. Открытый ключ используется для шифрования, а закрытый ключ — для расшифровки.

Полная программа для процедуры шифрования упомянута ниже —

from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP
from Crypto.Signature import PKCS1_v1_5
from Crypto.Hash import SHA512, SHA384, SHA256, SHA, MD5
from Crypto import Random
from base64 import b64encode, b64decode
hash = "SHA-256"

def newkeys(keysize):
   random_generator = Random.new().read
   key = RSA.generate(keysize, random_generator)
   private, public = key, key.publickey()
   return public, private

def importKey(externKey):
   return RSA.importKey(externKey)

def getpublickey(priv_key):
   return priv_key.publickey()

def encrypt(message, pub_key):
   cipher = PKCS1_OAEP.new(pub_key)
   return cipher.encrypt(message)

Шифрование RSA

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

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

def decrypt(ciphertext, priv_key):
   cipher = PKCS1_OAEP.new(priv_key)
   return cipher.decrypt(ciphertext)

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

авторизация

Авторизация — это процесс подтверждения того, что отправитель является единственным, кто передал сообщение. Следующий код объясняет это —

def sign(message, priv_key, hashAlg="SHA-256"):
   global hash
   hash = hashAlg
   signer = PKCS1_v1_5.new(priv_key)
   
   if (hash == "SHA-512"):
      digest = SHA512.new()
   elif (hash == "SHA-384"):
      digest = SHA384.new()
   elif (hash == "SHA-256"):
      digest = SHA256.new()
   elif (hash == "SHA-1"):
      digest = SHA.new()
   else:
      digest = MD5.new()
   digest.update(message)
   return signer.sign(digest)

Аутентификация

Аутентификация возможна методом проверки, который описан ниже:

def verify(message, signature, pub_key):
   signer = PKCS1_v1_5.new(pub_key)
   if (hash == "SHA-512"):
      digest = SHA512.new()
   elif (hash == "SHA-384"):
      digest = SHA384.new()
   elif (hash == "SHA-256"):
      digest = SHA256.new()
   elif (hash == "SHA-1"):
      digest = SHA.new()
   else:
      digest = MD5.new()
   digest.update(message)
   return signer.verify(digest, signature)

Цифровая подпись проверяется вместе с данными отправителя и получателя. Это добавляет больший вес в целях безопасности.

Шифрование RSA

Вы можете использовать следующий код для расшифровки RSA-шифра —

from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP
from Crypto.Signature import PKCS1_v1_5
from Crypto.Hash import SHA512, SHA384, SHA256, SHA, MD5
from Crypto import Random
from base64 import b64encode, b64decode
hash = "SHA-256"

def newkeys(keysize):
   random_generator = Random.new().read
   key = RSA.generate(keysize, random_generator)
   private, public = key, key.publickey()
   return public, private

def importKey(externKey):
   return RSA.importKey(externKey)

def getpublickey(priv_key):
   return priv_key.publickey()

def encrypt(message, pub_key):
   cipher = PKCS1_OAEP.new(pub_key)
   return cipher.encrypt(message)

def decrypt(ciphertext, priv_key):
   cipher = PKCS1_OAEP.new(priv_key)
   return cipher.decrypt(ciphertext)

def sign(message, priv_key, hashAlg = "SHA-256"):
   global hash
   hash = hashAlg
   signer = PKCS1_v1_5.new(priv_key)
   
   if (hash == "SHA-512"):
      digest = SHA512.new()
   elif (hash == "SHA-384"):
      digest = SHA384.new()
   elif (hash == "SHA-256"):
      digest = SHA256.new()
   elif (hash == "SHA-1"):
      digest = SHA.new()
   else:
      digest = MD5.new()
   digest.update(message)
   return signer.sign(digest)

def verify(message, signature, pub_key):
   signer = PKCS1_v1_5.new(pub_key)
   if (hash == "SHA-512"):
      digest = SHA512.new()
   elif (hash == "SHA-384"):
      digest = SHA384.new()
   elif (hash == "SHA-256"):
      digest = SHA256.new()
   elif (hash == "SHA-1"):
      digest = SHA.new()
   else:
      digest = MD5.new()
   digest.update(message)
   return signer.verify(digest, signature)

Взлом RSA Cipher

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

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

  • Атака по словарю не будет работать в алгоритме RSA, так как ключи являются числовыми и не содержат никаких символов.

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

  • Не существует специальных математических приемов для взлома RSA-шифра.

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

Атака по словарю не будет работать в алгоритме RSA, так как ключи являются числовыми и не содержат никаких символов.

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

Не существует специальных математических приемов для взлома RSA-шифра.

Уравнение расшифровки RSA —

M = C^d mod n

С помощью небольших простых чисел мы можем попробовать взломать RSA-шифр, и пример кода для него приведен ниже —

def p_and_q(n):
   data = []
   for i in range(2, n):
      if n % i == 0:
         data.append(i)
   return tuple(data)

def euler(p, q):
   return (p - 1) * (q - 1)

def private_index(e, euler_v):
   for i in range(2, euler_v):
      if i * e % euler_v == 1:
         return i

def decipher(d, n, c):
   return c ** d % n
	def main():
      e = int(input("input e: "))
      n = int(input("input n: "))
      c = int(input("input c: "))
      
      # t = 123
      # private key = (103, 143)
      p_and_q_v = p_and_q(n)
      # print("[p_and_q]: ", p_and_q_v)
      euler_v = euler(p_and_q_v[0], p_and_q_v[1])
      
      # print("[euler]: ", euler_v)
      d = private_index(e, euler_v)
      plain = decipher(d, n, c)
      print("plain: ", plain)
if __name__ == "__main__":
   main()

Выход

Приведенный выше код производит следующий вывод —