Python использует Crypto для расшифровки AES и шифрования файлов

 Предисловие : При написании программы сегодня:

Режим шифрования: AES/CBC/PKCS5Padding
Вектор инициализации шифрования: Пустой массив байтов длиной 16

Я никогда не понимал, как представить пустой массив байтов длиной 16

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

Справочная информация : для рабочих нужд некоторые данные шифруются для передачи, а другая сторона использует AES для шифрования пароля, и необходимо получить расшифрованные данные.
Цель : успешно расшифровать файл с помощью ключа.
Ключевые слова : AES_ECB, AES_CBC, проблемы с шифрованием AES в Java и Python,

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


1. Возникшие проблемы

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

key = 'Fcniggersm'
message = 'gYknrv3zMWYXEpRLDL0n8q+6s68DKapAfRpBDhN1XGM='

Расшифровать тестовый адрес


2. Введение в алгоритм AES

Подробное объяснение алгоритма AES : Advanced Encryption Standard, который является симметричным алгоритмом шифрования, AES имеет только один ключ, который используется как для шифрования, так и для дешифрования.

Существует пять методов шифрования AES: ECB , CBC , CTR, CFB, OFB.
Метод шифрования CBC рекомендуется с точки зрения безопасности.В этой статье представлена ​​реализация методов шифрования CBC и ECB на Python.

Шифрование CBC требует шестнадцатизначного ключа (ключа) и шестнадцатизначного iv (смещения).
Шифрование ECB не требует iv

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


3. Подготовка

python При использовании AES под Windows необходимо установить модуль pycryptodom
python При использовании AES под Linux необходимо установить модуль pycrypto

import base64
from Crypto.Cipher import AES
from Crypto import Random
import os
import base64
import json

4. Расшифровка и шифрование AES-ECB

1. Обработка ключей

Непосредственная обработка ключа сообщит об ошибке: «Ключ AES должен иметь длину 16, 24 или 32 байта»,
потому что key&vi, полученный AES, должен иметь фиксированную длину.
Заполняйте ключ до тех пор, пока он не будет соответствовать спецификации.

def add_to_16(text):
    while len(text) % 16 != 0:
        text += '\0'
    return (text)

key = 'Fcniggersm'
key = add_to_16(key) 

2. Обработка зашифрованного текста

Возможно, что при обработке зашифрованного текста будет сообщено об ошибке: "Ошибка: неправильное заполнение".
Это связано с тем, что длина зашифрованного текста не соответствует спецификациям. Просто заполните строку, декодированную base64, знаком равенства.

def decode_base64(data):
    missing_padding = 4-len(data)%4
    if missing_padding:
        data += b'='*missing_padding
    return (data)

message = 'gYknrv3zMWYXEpRLDL0n8q+6s68DKapAfRpBDhN1XGM='
encrypt_data = message 
encrypt_data = decode_base64(encrypt_data)

3. Обработка расшифровки

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

cipher = AES.new(key)
result2 = base64.b64decode(encrypt_data)
a = cipher.decrypt(result2)

a = a.decode('utf-8','ignore')
a = a.rstrip('\n')
a = a.rstrip('\t')
a = a.rstrip('\r')
a = a.replace('\x06','')
print('\n','data:',a)

#data: 儒雅随和,加大力度

4. Шифрование

Точно так же можно шифровать символы и выполнять методы шифрования и дешифрования AES .

 # encoding:utf-8

def encrypt(data, password):
    bs = AES.block_size
    pad = lambda s: s + (bs - len(s) % bs) * chr(bs - len(s) % bs)
    cipher = AES.new(password)
    data = cipher.encrypt(pad(data))
    return (data)
    
if __name__ == '__main__':
    data = 'ni hao'
    password = 'aesrsasec' #16,24,32位长的密码
    password = add_to_16(password)        
    encrypt_data = encrypt(data, password)
    encrypt_data = base64.b64encode(encrypt_data)
    print ('encrypt_data:', encrypt_data)

5. Расшифровка и шифрование AES-CBC

По сравнению с CBC и ECB здесь больше vi (офсет).
cipher = AES.new(self.__key, AES.MODE_CBC, iv)
двухстороннее симметричное шифрование и дешифрование python AES

# encoding:utf-8
import base64
from Crypto.Cipher import AES
from Crypto import Random
 
def encrypt(data, password):
    bs = AES.block_size
    pad = lambda s: s + (bs - len(s) % bs) * chr(bs - len(s) % bs)
    iv = Random.new().read(bs)
    cipher = AES.new(password, AES.MODE_CBC, iv)
    data = cipher.encrypt(pad(data))
    data = iv + data
    return (data)
 
def decrypt(data, password):
    bs = AES.block_size
    if len(data) <= bs:
        return (data)
    unpad = lambda s : s[0:-ord(s[-1])]
    iv = data[:bs]
    cipher = AES.new(password, AES.MODE_CBC, iv)
    data  = unpad(cipher.decrypt(data[bs:]))
    return (data)
 
if __name__ == '__main__':
    data = 'd437814d9185a290af20514d9341b710'
    password = '78f40f2c57eee727a4be179049cecf89' #16,24,32位长的密码
    encrypt_data = encrypt(data, password)
    encrypt_data = base64.b64encode(encrypt_data)
    print ('encrypt_data:', encrypt_data)
 
 
    encrypt_data = base64.b64decode(encrypt_data)
    decrypt_data = decrypt(encrypt_data, password)
    print ('decrypt_data:', decrypt_data)

6. Ошибка шифрования Java и расшифровки Python.

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

Причины возможных ошибок:
1. Алгоритм заполнения
2. Размер сегмента

Обратитесь к кроссплатформенной ошибке AES_CFB.


7. Ошибка расшифровки в Linux

Он работает без ошибок в Windows, но сообщает об ошибке при запуске в Lnuix.
①, ошибка new() отсутствует 1 обязательный позиционный аргумент:
в Linux необходимо добавить «режим», второй параметр, выберите режим шифрования (на этот раз выберите ECB)

cipher = AES.new(key ,AES.MODE_ECB)

②, Ошибка Тип объекта <class 'str'> не может быть передан в код C
Ключ, передаваемый в Linux, должен быть в форме байтов, и ключ обрабатывается

key = key.encode('utf-8')
cipher = AES.new(key ,AES.MODE_ECB)

8. Резюме

1. При работе с шифрованием AES вы должны согласовать конкретный метод шифрования.
2. Ключ vi должен быть соответствующей длины.
3. Также необходимо заполнить шифротекст.
4. Windows ECB автоматически добавляет параметр шифрования, а ключ может быть строкой. В linux нужно заполнить полные параметры и обработать ключ в байты.


Девять, другие

1. pad и unpad — это функция заполнения и обратная функция заполнения соответственно. Поскольку шифрование AES требует длины зашифрованного текста, оно должно быть кратно количеству байтов ключа. Длина encryptKey здесь после декодирования base64 составляет 16 байт.
2. На самом деле существует три типа шифрования AES: AES-128, AES-192 и AES-256, соответствующие трем длинам ключей: 128 бит (16 байт), 192 бит (24 байт) и 256 бит (32 байт). ). Конечно, чем длиннее ключ, тем выше безопасность и тем больше времени требуется для шифрования и расшифровки. По умолчанию используется AES-128, который полностью безопасен.

Расширение алгоритма заполнения

Алгоритм заполнения, используемый здесь, на самом деле имеет правильный термин, называемый pkcs7padding.
Простое объяснение состоит в том, чтобы восполнить недостающие биты: строка заполнения состоит из последовательности байтов, и каждый байт заполняет длину последовательности байтов заполнения.
Если вы хотите заполнить 8 байт, то значение заполненного байта равно 0x08, если вы хотите заполнить 7 байт, то заполненное значение равно 0x07 и так далее.
Если длина текста точно кратна длине BlockSize, значение длины BlockSize также будет заполнено. Преимущество этого в том, что количество заполненных байтов можно узнать по заполненному значению последнего байта.

Фактически, режим по умолчанию для реализации алгоритма шифрования AES в java — это Cipher.getInstance("AES/ECB/PKCS5Padding").
PKCS#5 является подмножеством PKCS#7 с точки зрения заполнения: PKCS#5 предназначен только для 8 байтов. ( BlockSize = 8) для заполнения, содержимое заполнения составляет 0x01-0x08; но PKCS # 7 не только заполняет 8 байтов, его диапазон BlockSize составляет 1-255 байт.
Однако, поскольку AES не имеет 64-битного (8-байтового) блока, при использовании PKCS5 по существу используется PKCS7.



Автор: Ziger,
Ссылка: https://www.jianshu.com/p/5b38b4187b54
Источник: Jianshu
Авторские права принадлежат автору. Для коммерческой перепечатки просьба обращаться к автору за авторизацией, для некоммерческой перепечатки просьба указывать источник.

Guess you like

Origin blog.csdn.net/m0_54219225/article/details/121532111