Prefácio : Ao escrever um programa hoje:
Modo de criptografia: AES/CBC/PKCS5Padding
Vetor de inicialização de criptografia: Matriz de bytes vazia com comprimento 16
Eu nunca entendi como representar uma matriz de bytes vazia com um comprimento de 16
Aí usei o modo ECB e descobri que a senha era a mesma do exemplo que ele deu, e a cabeça era grande.
Contexto : Para necessidades de trabalho, alguns dados são criptografados para transmissão e a outra parte usa AES para criptografar a senha, e os dados descriptografados precisam ser obtidos.
Objetivo : Descriptografar com sucesso um arquivo com uma chave.
Palavras-chave : AES_ECB, AES_CBC, problemas de criptografia AES em Java e Python,
criptografia AES
1. Problemas encontrados
Receba a chave e o arquivo criptografado da seguinte maneira. Uma chave é necessária para descriptografar as informações.
Dados conhecidos por serem criptografados com AES
key = 'Fcniggersm'
message = 'gYknrv3zMWYXEpRLDL0n8q+6s68DKapAfRpBDhN1XGM='
Descriptografar endereço de teste
2. Introdução ao Algoritmo AES
Explicação detalhada do algoritmo AES : Advanced Encryption Standard, que é um algoritmo de criptografia simétrico, o AES possui apenas uma chave, que é usada para criptografia e descriptografia.
Existem cinco métodos de criptografia AES: ECB , CBC , CTR, CFB, OFB.
O método de criptografia CBC é recomendado do ponto de vista da segurança. Este artigo apresenta a implementação Python dos métodos de criptografia CBC e ECB.
A criptografia CBC requer uma chave de dezesseis dígitos (chave) e uma criptografia de dezesseis dígitos iv (offset)
ECB não requer iv
Os dados recebidos possuem apenas chaves e nenhum deslocamento. Portanto, o ECB é usado para processar o texto cifrado.
3. Preparação
python Ao usar o AES no Windows, você precisa instalar o módulo pycryptodome
python Ao usar o AES no Linux, você precisa instalar o módulo pycrypto
import base64
from Crypto.Cipher import AES
from Crypto import Random
import os
import base64
import json
4. Descriptografia e Criptografia AES-ECB
1. Processamento de chaves
O processamento direto da chave relatará um erro: 'A chave AES deve ter 16, 24 ou 32 bytes de comprimento'
porque a chave&vi recebida pelo AES deve ter um comprimento fixo.
Preencha a Chave até que ela atenda à especificação.
def add_to_16(text):
while len(text) % 16 != 0:
text += '\0'
return (text)
key = 'Fcniggersm'
key = add_to_16(key)
2. Processamento de texto cifrado
É possível que seja reportado um erro ao processar o texto cifrado: 'Erro: Preenchimento incorreto'.
Isso ocorre porque o comprimento do texto cifrado não atende às especificações. Basta preencher a string decodificada por base64 com um sinal de igual.
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. Processamento de descriptografia
A descriptografia obtém com sucesso um e, em seguida, decodifica um para obter dados.
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. Processamento de criptografia
Da mesma forma, os caracteres podem ser criptografados e os métodos de criptografia e descriptografia AES podem ser implementados .
# 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. Descriptografia e criptografia AES-CBC
Comparado com CBC & ECB, há mais um vi (offset).
cipher = AES.new(self.__key, AES.MODE_CBC, iv)
python AES criptografia e descriptografia simétrica bidirecional
# 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. Criptografia Java e erro de descriptografia Python.
No trabalho real do AES, descobriu-se que o arquivo criptografado pelo Java da outra parte e o texto cifrado criptografado por seu próprio Python eram diferentes, resultando em erros de descriptografia entre plataformas.
Razões para possíveis erros:
1. Algoritmo de preenchimento
2. Tamanho do segmento
Consulte o erro de plataforma cruzada AES_CFB
7. Erro de descriptografia no Linux
Ele roda sem erro no windows, mas reporta um erro quando roda no Lnuix.
①, erro new() faltando 1 argumento posicional necessário: 'modo'
precisa ser adicionado no linux, o segundo parâmetro, selecione o modo de criptografia (desta vez, escolha ECB)
cipher = AES.new(key ,AES.MODE_ECB)
②, Erro Tipo de objeto <class 'str'> não pode ser passado para o código C
A chave passada no linux deve estar na forma de bytes, e a chave é processada
key = key.encode('utf-8')
cipher = AES.new(key ,AES.MODE_ECB)
8. Resumo
1. Ao lidar com criptografia AES, você deve concordar com um método de criptografia específico.
2. Chave, vi deve ter um comprimento compatível.
3. O texto cifrado também precisa ser preenchido.
4. O Windows ECB adiciona automaticamente o parâmetro cipher e a chave pode ser uma string. No Linux, você precisa preencher os parâmetros completos e processar a chave em bytes.
nove, outro
1. pad e unpad são função de preenchimento e função de preenchimento inverso, respectivamente. Como a criptografia AES tem um requisito de comprimento para o texto criptografado, ele deve ser um múltiplo do número de bytes de chave. O comprimento do encryptKey aqui após a decodificação base64 é de 16 bytes.
2. Na verdade, existem três tipos de criptografia AES, AES-128, AES-192 e AES-256, correspondendo aos três comprimentos de chave de 128 bits (16 bytes), 192 bits (24 bytes) e 256 bits (32 bytes) ). Obviamente, quanto maior a chave, maior a segurança e mais tempo leva para criptografar e descriptografar. O padrão é AES-128, que é totalmente seguro.
Extensão do Algoritmo de Preenchimento
O algoritmo de preenchimento usado aqui, na verdade, tem um termo apropriado chamado pkcs7padding.
A explicação simples é compensar os bits ausentes: a string de preenchimento consiste em uma sequência de bytes e cada byte preenche o comprimento da sequência de bytes de preenchimento.
Se você deseja preencher 8 bytes, o valor do byte preenchido é 0x08; se deseja preencher 7 bytes, o valor preenchido é 0x07; e assim por diante.
Se o comprimento do texto for exatamente um múltiplo do comprimento do BlockSize, um valor do comprimento do BlockSize também será preenchido. A vantagem disso é que o número de bytes preenchidos pode ser conhecido de acordo com o valor preenchido do último Byte.
Na verdade, o modo padrão para implementar o algoritmo de criptografia AES em java é Cipher.getInstance("AES/ECB/PKCS5Padding")
PKCS#5 é um subconjunto de PKCS#7 em termos de preenchimento: PKCS#5 é apenas para 8 bytes ( BlockSize=8) para preenchimento, o conteúdo do preenchimento é 0x01-0x08; mas PKCS#7 não é apenas preenchimento para 8 bytes, seu intervalo de BlockSize é de 1-255 bytes.
No entanto, como o AES não possui um bloco de 64 bits (8 bytes), se o PKCS5 for usado, o PKCS7 será essencialmente usado.
Autor: Ziger,
Link: https://www.jianshu.com/p/5b38b4187b54
Fonte: Jianshu
Os direitos autorais pertencem ao autor. Para reimpressão comercial, por favor, entre em contato com o autor para autorização, para reimpressão não comercial, por favor, indique a fonte.