Общие методы шифрования и реализация Python

Python

Адрес этой статьи:Краткое описание.com/afraid/4 20 фарфоровых изделий Альфа…

предисловие

Мы говорим о шифровании, шифруется двоичный формат, который соответствует Python, это нашBytes.

Поэтому, когда мы выполняем криптографические операции в Python, убедитесь, что мы работаем сBytes, иначе будет сообщено об ошибке.

строка иBytesВзаимное преобразование может быть использованоencode()иdecode()метод. Следующее:

# 方法中不传参数则是以默认的utf-8编码进行转换
In [1]: '南北'.encode()
Out[1]: b'\xe5\x8d\x97\xe5\x8c\x97'

In [2]: b'\xe5\x8d\x97\xe5\x8c\x97'.decode()
Out[2]: '南北'

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

использоватьbinasciiМодуль может преобразовывать байты, отображаемые в шестнадцатеричном формате, в более часто используемые методы отображения при шифровании и дешифровании:

In [1]: import binascii

In [2]: '南北'.encode()
Out[2]: b'\xe5\x8d\x97\xe5\x8c\x97'

In [3]: binascii.b2a_hex('南北'.encode())
Out[3]: b'e58d97e58c97'

In [4]: binascii.a2b_hex(b'e58d97e58c97')
Out[4]: b'\xe5\x8d\x97\xe5\x8c\x97'

In [5]: binascii.a2b_hex(b'e58d97e58c97').decode()
Out[5]: '南北'

Кодировка URL

Введение

Обычный URL-адрес может содержать только символы ASCII, то есть символы, цифры и некоторые символы. Кодирование URL-адресов — это метод кодирования, используемый браузерами для исключения использования специальных символов (например, китайских иероглифов) в URL-адресах.

По сути, это преобразование символов за пределами диапазона ASCII в%в шестнадцатеричном формате.

Реализация Python

In [1]: from urllib import parse

# quote()方法会自动将str转换成bytes,所以这里传入str和bytes都可以
In [2]: parse.quote('南北')
Out[2]: '%E5%8D%97%E5%8C%97'

In [3]: parse.unquote('%E5%8D%97%E5%8C%97')
Out[3]: '南北'

Кодировка Base64

Кратко

Base64 — это способ представления произвольных двоичных данных в 64 символа.

Кодирование Base64 может быть краеугольным камнем криптографии. Произвольные двоичные данные могут быть закодированы в Base64. Все данные можно закодировать и представить в виде текстовых файлов, используя всего 64 символа. ( 64 символа: A~Z a~z 0~9 + / ) Закодированные данные ~= 4/3 данных до кодирования, которые будут примерно на 1/3 больше.

Принцип кодирования Base64

1524836141496.png
  1. Преобразование всех символов в ASCII.
  2. Преобразование ASCII в 8-битный двоичный код.
  3. Сгруппируйте 3 двоичных бита в группу (если меньше 3, добавьте 0 сзади) до 24 бит, а затем разделите их на 4 группы по 6 бит в каждой.
  4. Равномерно добавьте два 0 перед 6-битным двоичным кодом, чтобы получить 8 бит.
  5. Преобразуйте двоичный файл с нулевым дополнением в десятичный.
  6. Получите кодировку Base64, соответствующую десятичному, из таблицы кодировки Base64.

Описание кодировки Base64

  1. При преобразовании поместить три байта данных в 24-битный буфер один за другим, причем первый байт занимает старшую позицию.
  2. Если данные меньше 3 байт, оставшиеся биты в буфере заполняются 0. Затем каждый раз извлекается 6 бит, и соответствующий символ выбирается в качестве закодированного вывода в соответствии с справочной таблицей выбора его значения.
  3. Продолжайте, пока все преобразования входных данных не будут завершены.
  4. Если в конце осталось два входных данных, добавьте 1 "=" после результата кодирования.
  5. Если в конце остались одни входные данные, добавьте 2 "=" после результата кодирования.
  6. Если данных не осталось, ничего не добавляйте, чтобы обеспечить корректность восстановления данных.

Использование Python Base64

Встроенный Pythonbase64Модуль может напрямую кодировать и декодировать base64.

Примечание. Для кодировки base64 используются либо символы, содержащиеся в ASCII, либо двоичные данные.

In [1]: import base64

In [2]: base64.b64encode(b'hello world')
Out[2]: b'aGVsbG8gd29ybGQ='

In [3]: base64.b64decode(b'aGVsbG8gd29ybGQ=')
Out[3]: b'hello world'

MD5 (алгоритм дайджеста сообщения)

Кратко

алгоритм дайджеста сообщения 5 (алгоритм дайджеста сообщения). «Шифрование MD5», о котором часто говорят, это → алгоритм переваривания информации.

md5 на самом деле является алгоритмом. Строка, файл или сжатый пакет могут быть выполнены после md5 для создания строки с фиксированной длиной 128 бит. Эта строка в основном уникальна.

необратимость

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

Функции

  1. Сжимаемость: для данных любой длины длина вычисляемого значения MD5 является фиксированной.
  2. Простой расчет: легко рассчитать значение MD5 на основе исходных данных.
  3. Устойчивость к модификации: любая модификация исходных данных, даже если изменен только 1 байт, полученное значение MD5 сильно отличается.
  4. Сильное предотвращение столкновений: зная исходные данные и их значение MD5, очень сложно найти данные с таким же значением MD5 (то есть поддельные данные).

Возьмем каштан: в мире есть только один я, но столько девушек. С ограниченным мной и почти неограниченным количеством девушек можно получить много (100+) девушек. Эта теория действительно верна. Хорошо, а на самом деле...

Использование Python MD5

Поскольку модуль MD5 был удален в python3, используйте в python3hashlibМодуль для работы md5

import hashlib

# 待加密信息
str = '这是一个测试'

# 创建md5对象
hl = hashlib.md5()

# 此处必须声明encode
# 若写法为hl.update(str)  报错为: Unicode-objects must be encoded before hashing
hl.update(str.encode())

print('MD5加密前为 :' + str)
print('MD5加密后为 :' + hl.hexdigest())

результат операции

MD5加密前为 :这是一个测试
MD5加密后为 :cfca700b9e09cf664f3ae80733274d9f

Длина MD5

Длина md5, по умолчанию 128бит, то есть 128 бинарных строк 0 и 1. Это выражение очень недружелюбно. Таким образом, двоичное число преобразуется в шестнадцатеричное, и каждые 4 бита представляют собой шестнадцатеричное число, поэтому 128/4 = 32 преобразуется в шестнадцатеричное, и это 32 бита.

Почему в интернете есть md5, который 16-битный?

На самом деле 16-битная длина получена из 32-битного значения md5. Он получается путем удаления первых восьми бит и последних восьми бит 32-битного файла md5.

Библиотека шифрования Python PyCryptodome

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

К счастью, есть форк проекта PyCrytodome, который заменяет PyCrypto.

установить и импортировать

Windows должна быть установлена ​​перед установкойMicrosoft Visual c++ 2015.

ссылка для скачивания:Woohoo. Microsoft.com/en-US/down…

Для установки в Linux вы можете использовать следующую команду pip:

pip install pycryptodome

Импортировать:

import Crypto

Установка в системах Windows немного отличается:

pip install pycryptodomex

Импортировать:

import Cryptodome

DES

Введение

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

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

Алгоритм DES имеет три входных параметра: ключ, данные и режим. Среди них ключ — 7 байтов с общим количеством битов 56, что является рабочим ключом алгоритма DES; данные — 8 байтов и 64 бита, то есть данные, которые необходимо зашифровать или расшифровать; режим — рабочий режим DES, два вида: шифрование или дешифрование.

Ключ имеет длину 64 бита, и на самом деле ключ состоит из 56 битов, участвующих в операции DES (8-й, 16-й, 24-й, 32-й, 40-й, 48-й, 56-й и 64-й биты являются контрольными цифрами, так что каждый ключ имеет нечетное число). из единиц), сгруппированная группа открытого текста и 56-битный ключ образуют группу зашифрованного текста путем побитовой замены или обмена.

пример

# 导入DES模块
from Cryptodome.Cipher import DES
import binascii

# 这是密钥
key = b'abcdefgh'
# 需要去生成一个DES对象
des = DES.new(key, DES.MODE_ECB)
# 需要加密的数据
text = 'python spider!'
text = text + (8 - (len(text) % 8)) * '='

# 加密的过程
encrypto_text = des.encrypt(text.encode())
encrypto_text = binascii.b2a_hex(encrypto_text)
print(encrypto_text)

3DES

Введение

3DES (или Triple DES) — это общий термин для блочного шифра алгоритма тройного шифрования данных (TDEA, Triple Data Encryption Algorithm). Это эквивалентно трем применениям алгоритма шифрования DES к каждому блоку данных.

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

3DES (т.е. Triple DES) представляет собой алгоритм шифрования, переходный от DES к AES (в 1999 г. NIST определил 3-DES в качестве переходного стандарта шифрования).Алгоритм шифрования реализован следующим образом: Пусть Ek() и Dk() представляют DES. алгоритм Процесс шифрования и дешифрования , K представляет собой ключ, используемый алгоритмом DES, M представляет собой открытый текст, а C представляет зашифрованный текст следующим образом:

Процесс шифрования 3DES: C=Ek3(Dk2(Ek1(M)))

Процесс расшифровки 3DES: M=Dk1(EK2(Dk3(C)))

AES

Введение

Расширенный стандарт шифрования(Английский:Advanced Encryption Standard,сокращение:AES), также известный в криптографииШифрование Rijndael, — это стандарт блочного шифрования, принятый федеральным правительством США. Этот стандарт используется для замены оригинального DES, который был проанализирован многими сторонами и широко используется во всем мире. После пятилетнего отбора Advanced Encryption Standard был опубликован Национальным институтом стандартов и технологий (NIST) в FIPS PUB 197 26 ноября 2001 г. и стал действующим стандартом 26 мая 2002 г. В 2006 году Advanced Encryption Standard стал одним из самых популярных алгоритмов шифрования с симметричным ключом.

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

Особенности и идеи

  1. Сопротим всех известных атак.
  2. Высокая скорость на нескольких платформах и компактное кодирование.
  3. Простой дизайн.

Детальное объяснение

1524901614191.png

AES — это блочный шифр.Блочный шифр делит открытый текст на группы одинаковой длины и шифрует группу данных за раз, пока не будет зашифрован весь открытый текст. В стандартной спецификации AES длина блока может быть только 128 бит, то есть каждый блок равен 16 байтам (по 8 бит на байт). Длина ключа может быть 128 бит, 192 бит или 256 бит. Длина ключа разная, и рекомендуемое количество раундов шифрования тоже разное.

128-бит обычно используется

Реализация Python

from Cryptodome.Cipher import AES
from Cryptodome import Random
from binascii import b2a_hex  

# 要加密的明文
data = '南来北往'
# 密钥key 长度必须为16(AES-128)、24(AES-192)、或32(AES-256)Bytes 长度.
# 目前AES-128足够用
key = b'this is a 16 key'
# 生成长度等于AES块大小的不可重复的密钥向量
iv = Random.new().read(AES.block_size)

# 使用key和iv初始化AES对象, 使用MODE_CFB模式
mycipher = AES.new(key, AES.MODE_CFB, iv)
# 加密的明文长度必须为16的倍数,如果长度不为16的倍数,则需要补足为16的倍数
# 将iv(密钥向量)加到加密的密文开头,一起传输
ciphertext = iv + mycipher.encrypt(data.encode())

# 解密的话要用key和iv生成新的AES对象
mydecrypt = AES.new(key, AES.MODE_CFB, ciphertext[:16])
# 使用新生成的AES对象,将加密的密文解密
decrypttext = mydecrypt.decrypt(ciphertext[16:])


print('密钥k为:', key)
print('iv为:', b2a_hex(ciphertext)[:16])
print('加密后数据为:', b2a_hex(ciphertext)[16:])
print('解密后数据为:', decrypttext.decode())

результат операции:

密钥k为: b'this is a 16 key'
iv为: b'a78a177cffd50878'
加密后数据为: b'33f61e7678c25d795d565d40f2f68371da051202'
解密后数据为: 南来北往

RSA

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

Типичные методы, такие как RSA и т. д., используют такие инструменты, как openssl и keytools, для создания пары открытого и закрытого ключей Данные, зашифрованные открытым ключом, могут быть расшифрованы закрытым ключом, и наоборот (данные, зашифрованные закрытым ключом). также может быть расшифрован открытым ключом).

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

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

Введение

Алгоритм шифрования RSAэто非对称加密算法. RSA широко используется в шифровании с открытым ключом и электронной коммерции.

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

Реализация Python

Сначала нам нужно установитьrsaМодуль:

pip install rsa

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

Шифрование данных с помощью открытого ключа на веб-странице

import rsa
import binascii

# 使用网页中获得的n和e值,将明文加密
def rsa_encrypt(rsa_n, rsa_e, message):
    # 用n值和e值生成公钥
    key = rsa.PublicKey(rsa_n, rsa_e)
    # 用公钥把明文加密
    message = rsa.encrypt(message.encode(), key)
    # 转化成常用的可读性高的十六进制
    message = binascii.b2a_hex(message)
    # 将加密结果转化回字符串并返回
    return message.decode()

# RSA的公钥有两个值n和e,我们在网站中获得的公钥一般就是这样的两个值。
# n常常为长度为256的十六进制字符串
# e常常为十六进制‘10001’
pubkey_n = '8d7e6949d411ce14d7d233d7160f5b2cc753930caba4d5ad24f923a505253b9c39b09a059732250e56c594d735077cfcb0c3508e9f544f101bdf7e97fe1b0d97f273468264b8b24caaa2a90cd9708a417c51cf8ba35444d37c514a0490441a773ccb121034f29748763c6c4f76eb0303559c57071fd89234d140c8bb965f9725'
pubkey_e = '10001'
# 需要将十六进制转换成十进制
rsa_n = int(pubkey_n, 16)
rsa_e = int(pubkey_e, 16)
# 要加密的明文
message = '南北今天很忙'

print("公钥n值长度:", len(pubkey_n))
print(rsa_encrypt(rsa_n, rsa_e, message))

результат операции:

公钥n值长度: 256
480f302eed822c8250256511ddeb017fcb28949cc05739ae66440eecc4ab76e7a7b2f1df398aefdfef2b9bfce6d6152bf6cc1552a0ed8bebee9e094a7ce9a52622487a6412632144787aa81f6ec9b96be95890c4c28a31b3e8d9ea430080d79297c5d75cd11df04df6e71b237511164399d72ccb2f4c34022b1ea7b76189a56e