Página 1 de 1

AES - Advanced Encryption Standard - Criptografia

Enviado: 09 Mai 2016 09:57
por yugi386
Saudações!

Prezados amigos,

Fiz uma implementação do algoritmo AES - Advanced Encryption Standard. Referência Técnica em: http://csrc.nist.gov/publications/fips/ ... ps-197.pdf
O código está em um único arquivo (aes.prg) e está valido de acordo com a referência técnica. O objetivo foi estudar em detalhes o algoritmo AES-128, onde a chave e o bloco de cifragem tem 128 bits.
Parece que o Harbour já implementa uma função para o AES mas como meu objetivo foi de estudo resolvi implementá-lo linha a linha.

Para criptografar um texto o procedimento é:

Código: Selecionar todos

                iniciarAES()	// antes de chamar quaisquer funções é necessário executar esta chamada

		texto:= "A criptografia é uma ciência enigmática!"
		chave:= "2b 7e 15 16 28 ae d2 a6 ab f7 15 88 09 cf 4f 30"

		? texto
		cifrado := cifraTextoCompleto(texto,chave)
		? cifrado
		decifrado:= decifraTextoCompleto(cifrado,chave)
		 ? decifrado
Observem que o texto é informado em ASCII e a chave em hexadecimal. O texto cifrado é gerado em base64. A entrada para a decifragem é em base64 mas a saída será em texto puro.
Resolvi deixar a saída do texto cifrado em base64 porque assim podemos copiar e colocar o criptograma em qualquer lugar. Se deixasse em ASCII esbarraria no problema dos caracteres não imprimíveis.
Uma outra opção seria deixar a saída do criptograma em formato hexadecimal mas no formato base64 a string fica menor.

Para criptografar um arquivo o procedimento é:

Código: Selecionar todos

                iniciarAES()	// antes de chamar quaisquer funções é necessário executar esta chamada

 // Os parametros das funções de cifragem e decifragem são: [nome do arquivo de origem], [nome do arquivo destino], [chave em hexadecimal]
// OBS: se o arquivo de destino já existir será sobrescrito.

		cifraArquivo("f.pdf","f_aes.pdf",chave)
		decifraArquivo("f_aes.pdf","g.pdf",chave)

Naturalmente os arquivos são gravados no formato binário. A chave deve estar em formato hexadecimal e deve ter tamanho 32. Os espaços contidos na chave em hexadecimal serão automaticamente eliminados.
Em anexo está o fonte completo e o arquivo de referência do algoritmo AES que também será usado para um teste de criptografia e decifragem.

Para compilar o sistema nada mais fácil: compila.bat que está no pacote anexo junto com o fonte e o arquivo de referência técnica para teste.

att,

Yugi.

Código fonte para os curiosos de plantão!!!

Código: Selecionar todos

/*
___________________________________________________________________________________________________
Implementação do algoritmo AES - ADVANCED ENCRYPTION STANDARD
___________________________________________________________________________________________________
Programador.........: Yugi
Referência Técnica..: Federal Information Processing Standards Publication 197 November 26, 2001
Padrão do AES.......: Chave de 128 bits | Bloco de cifragem de 128 bits

Para compilar use: hbmk2 aes -lhbnf -lhbmisc -static -lhbct
___________________________________________________________________________________________________
*/ 

function main()
	local ct, chave, texto, ct2

	cls
	ylib_iniciar()

	/* 	Exemplo de cifragem de texto:
		texto-> Entrada em formato ASCII
		chave-> Entrada em formato Hexadecimal (pode conter espaços que serão eliminados automaticamente)
		texto cifrado é apresentado em base64 
	*/

		iniciarAES()	// antes de chamar quaisquer funções é necessário executar esta chamada

		texto:= "A criptografia é uma ciência enigmática!"
		chave:= "2b 7e 15 16 28 ae d2 a6 ab f7 15 88 09 cf 4f 30"

		? texto
		cifrado := cifraTextoCompleto(texto,chave)
		? cifrado
		decifrado:= decifraTextoCompleto(cifrado,chave)
		? decifrado

		if alltrim(decifrado) <> alltrim(texto)
			? "erro"
		endif

		/*
		Exemplo de criptografia de arquivos:	
			Informe o nome do arquivo, o nome do arquivo destino e a chave de cifragem
			Na decifragem os parametros são os mesmos
			chave deve ser informada em formato hexadecimal
			OBS: se os arquivos destino existirem serão sobrescritos sem prévio aviso!!!!
		*/

		chave:= "627bceb9999d5aaac945ecf423f56da5"

		? time()
		cifraArquivo("f.pdf","f_aes.pdf",chave)
		? time()
		decifraArquivo("f_aes.pdf","g.pdf",chave)
		? time()		

return NIL

/*
___________________________________________________________________________________________________
FUNÇÃO cifraArquivo()
Faz a cifragem de um arquivo
Parametros: nome do arquivo origem + nome arquivo destino + chave em hexadecimal
___________________________________________________________________________________________________
*/ 
function cifraArquivo(arquivo,arqdestino, chave)
local ct, ct2, tamfile, nulas:=0, tam, ler:=space(16), arq, dest, ct3,posic, stringNula:="", modoCBC:=""

	if !file(arquivo)
		? "Arquivo não encontrado!"
		quit
	endif

	tamfile:=filesize(arquivo)	// tamanho do arquivo a ser cifrado
	nulas = 16 - (tamfile % 16)
	nulas = nulas % 16

	stringNulas:= chr(nulas)
	for ct:=1 to 15
		stringNulas+= chr(int(hb_random(256))% 256)
	next

	calculaChaveExpandida(chave)

	tam = int(tamfile / 16)	// limite do arquivo

	arq := fopen(arquivo)	
	// dest:= fcreate((arquivo + ".aes"))
	dest:= fcreate(arqdestino)

	fwrite(dest,stringNulas,16)	// grava o controle de nulas no arquivo destino

		modoCBC:=stringNulas	// implementa o modo de cifragem de encadeamento de blocos
			posic=1
			// Carregando a matriz texto corrente:
			for ct2:= 1 to 4
				for ct3:= 1 to 4
					estadoChave[ct3,ct2]:= asc( substr(modoCBC,posic,1) )
					posic+=1
				next
			next

	for ct:= 1 to tam
		fread(arq,@ler,16)

		posic=1
		// Carregando a matriz texto corrente:
		for ct2:= 1 to 4
			for ct3:= 1 to 4
				// textoCorrente[ct3,ct2]:= asc( substr(ler,posic,1) )
				textoCorrente[ct3,ct2]:= fxor ( asc( substr(ler,posic,1) ), estadoChave[ct3,ct2])	// modo CBC
				posic+=1
			next
		next
		
			addRoundKey(1)	// insere chave
			for ct2:= 2 to 10
				subBytes()
				shiftRows()
				mixColumns()
				addRoundKey(ct2)	// insere chave					
			next
				subBytes()
				shiftRows()
				addRoundKey(11)	// insere chave				

		// gravando no arquivo destino:
		for ct2:= 1 to 4
			for ct3:= 1 to 4
				fwrite(dest,chr(textoCorrente[ct3,ct2]),1)
				estadoChave[ct3,ct2]=textoCorrente[ct3,ct2]  // modo CBC
			next
		next

	next

	// Controle de bytes nulos para que o tamanho do arquivo seja múltiplo de 16
	if nulas <> 0
		tam = tamfile-tam
		ler = space(tam)
		fread(arq,@ler,tam)

		for ct:=1 to nulas
			ler += chr(int(hb_random(256))% 256)
		next
		
		posic=1
		// Carregando a matriz texto corrente:
		for ct2:= 1 to 4
			for ct3:= 1 to 4
				// textoCorrente[ct3,ct2]:= asc( substr(ler,posic,1) )
				textoCorrente[ct3,ct2]:= fxor ( asc( substr(ler,posic,1) ), estadoChave[ct3,ct2])	// modo CBC
				posic+=1
			next
		next

			addRoundKey(1)	// insere chave
			for ct2:= 2 to 10
				subBytes()
				shiftRows()
				mixColumns()
				addRoundKey(ct2)	// insere chave					
			next
				subBytes()
				shiftRows()
				addRoundKey(11)	// insere chave				

		// gravando no arquivo destino:
		for ct2:= 1 to 4
			for ct3:= 1 to 4
				fwrite(dest,chr(textoCorrente[ct3,ct2]),1)
			next
		next
	endif

	fclose(arq)
	fclose(dest)

return NIL


/*
___________________________________________________________________________________________________
FUNÇÃO decifraArquivo()
Faz a decifragem de um arquivo
Parametros: nome do arquivo origem + nome arquivo destino + chave em hexadecimal
___________________________________________________________________________________________________
*/ 
function decifraArquivo(arquivo,arqdestino,chave)
local ct, ct2, tamfile, nulas:=0, tam, ler:=space(16), arq, dest, ct3,posic,  modoCBC:=""

	if !file(arquivo)
		? "Arquivo não encontrado!"
		quit
	endif

	tamfile:=filesize(arquivo)	// tamanho do arquivo a ser cifrado
	/*
	nulas = 16 - (tamfile % 16)
	nulas = nulas % 16
	*/
	calculaChaveExpandida(chave)

	tam = tamfile - 16
	tam = int(tam / 16)	// limite do arquivo

	arq := fopen(arquivo)	
	// dest:= fcreate((arquivo + ".dec"))
	dest:= fcreate(arqdestino)

	fread(arq,@ler,16)	// lendo o vetor inicial que contém informações sobre nulas
	nulas = asc(substr(ler,1,1))

		modoCBC:=ler	// implementa o modo de decifragem com encadeamento de blocos
			posic=1
			// Carregando a matriz texto corrente:
			for ct2:= 1 to 4
				for ct3:= 1 to 4
					estadoChave[ct3,ct2]:= asc( substr(modoCBC,posic,1) )
					posic+=1
				next
			next
		modoCBC:=""
	

	if nulas <> 0
		tam=tam-1	// é preciso para ler o ultimo bloco de modo diferenciado
	endif

	for ct:= 1 to tam
		fread(arq,@ler,16)

		modoCBC:=""
		posic=1
		// Carregando a matriz texto corrente:
		for ct2:= 1 to 4
			for ct3:= 1 to 4
				textoCorrente[ct3,ct2]:= asc( substr(ler,posic,1) )
				modoCBC+=substr(ler,posic,1)  // salva informações para modo CBC
				posic+=1
			next
		next
		
		// decifragem:

		addRoundKey(11)	// insere chave
		shiftRowsInversa()
		subBytesInversa()

		for ct2:= 10 to 2 step -1
			addRoundKey(ct2)	// insere chave					
			mixColumnsInversa()
			shiftRowsInversa()
			subBytesInversa()
		next
		addRoundKey(1)	// insere chave					

		// gravando no arquivo destino:
		for ct2:= 1 to 4
			for ct3:= 1 to 4
				textoCorrente[ct3,ct2] = fxor(textoCorrente[ct3,ct2],estadoChave[ct3,ct2] )	// modo CBC
				fwrite(dest,chr(textoCorrente[ct3,ct2]),1)
			next
		next

		// código para gerenciar o modo CBC para a proxima volta		
		posic=1
		for ct2:= 1 to 4
			for ct3:= 1 to 4
				estadoChave[ct3,ct2]:= asc( substr(modoCBC,posic,1) )
				posic+=1
			next
		next		

	next

	if nulas <> 0
		nulas = 16 - nulas
		fread(arq,@ler,16)
		
		posic=1
		// Carregando a matriz texto corrente:
		for ct2:= 1 to 4
			for ct3:= 1 to 4
				textoCorrente[ct3,ct2]:= asc( substr(ler,posic,1) )
				posic+=1
			next
		next

		addRoundKey(11)	// insere chave
		shiftRowsInversa()
		subBytesInversa()

		for ct2:= 10 to 2 step -1
			addRoundKey(ct2)	// insere chave					
			mixColumnsInversa()
			shiftRowsInversa()
			subBytesInversa()
		next
		addRoundKey(1)	// insere chave					

		// gravando no arquivo destino:
		posic = 0
		for ct2:= 1 to 4
			for ct3:= 1 to 4
				textoCorrente[ct3,ct2] = fxor(textoCorrente[ct3,ct2],estadoChave[ct3,ct2] )	// modo CBC
				fwrite(dest,chr(textoCorrente[ct3,ct2]),1)
				++posic
				if posic >= nulas
					exit
				endif
			next
			if posic >= nulas
				exit
			endif
		next
	endif

	fclose(arq)
	fclose(dest)

return NIL

/*
___________________________________________________________________________________________________
FUNÇÃO cifraTextoCompleto()
Faz a cifragem de vários blocos e retorna o resultado
Parametros: texto em string e chave em hexadecimal
___________________________________________________________________________________________________
*/ 
function cifraTextoCompleto(texto,chave)
local vetorTexto:={}, ct, ret:=space(0)
	
	// Preparando o texto em formato ASCII - o texto tem que ter tamanho multiplo de 16
	tam = len(texto)
	texto += replicate(" ",16-(tam % 16))
	tam = len(texto)

	// Convertendo texto para Hexadecimal
	for ct:= 1 to tam step 16
		aadd(vetorTexto,converteTextoParaHexadecimal( substr(texto,ct,16) ) )
	next

	tam:= len(vetorTexto)

	for ct:= 1 to tam
		ret += cifraTexto(vetorTexto[ct],chave)
	next

	ret:= converteHexadecimalParaBase64(ret)

return ret

/*
___________________________________________________________________________________________________
FUNÇÃO decifraTextoCompleto()
Faz a decifragem de vários blocos e retorna o resultado
Parametros: texto em base64 e chave em hexadecimal
___________________________________________________________________________________________________
*/ 
function decifraTextoCompleto(texto,chave)
local vetorTexto:={}, ct, ret:=""
	
	texto:= converteBase64ParaHexadecimal(texto)
	texto:= strtran(alltrim(upper(texto))," ","")

	tam = len(texto)
	if tam % 16 <> 0
		? "O texto cifrado tem tamanho inválido: Não é múltiplo de 16!"
		quit
	endif

	// Adicionando o criptograma ao vetor
	for ct:= 1 to tam step 32
		aadd(vetorTexto,substr(texto,ct,32) ) 
	next

	tam:= len(vetorTexto)

	for ct:= 1 to tam
		ret += converteHexadecimalParaTexto( decifraTexto(vetorTexto[ct],chave) )
	next

return alltrim(ret)

/*
___________________________________________________________________________________________________
FUNÇÃO cifraTexto()
Faz a cifragem de um bloco
Parametros: texto e chave em hexadecimal
___________________________________________________________________________________________________
*/ 
function cifraTexto(texto,chave)
local posic, ct, ct2, ret:="", msg
	
	texto:=strtran(alltrim(upper(texto))," ","")
	calculaChaveExpandida(chave)

	// Validação dos caracteres do bloco de texto
	msg = validaHexadecimal(texto)
	if !empty(msg)
		? "Erro no texto!!!"
		? msg
		quit
	endif

	// Carregando a matriz texto corrente:
	posic=1
	for ct:= 1 to 4
		for ct2:= 1 to 4
			textoCorrente[ct2,ct]:= hex_dec( substr(texto,posic,2) )
			posic+=2
		next
	next
	
	// cifragem:

		addRoundKey(1)	// insere chave
		for ct:= 2 to 10
			subBytes()
			shiftRows()
			mixColumns()
			addRoundKey(ct)	// insere chave					
		next
			subBytes()
			shiftRows()
			addRoundKey(11)	// insere chave					

		for ct:= 1 to 4
			for ct2:= 1 to 4
				ret+= dec_hex(textoCorrente[ct2,ct]) // + " "
			next
		next

return alltrim(ret)

/*
___________________________________________________________________________________________________
FUNÇÃO decifraTexto()
Faz a decifragem de um bloco
Parametros: texto e chave em hexadecimal
___________________________________________________________________________________________________
*/ 
function decifraTexto(texto,chave)
local posic, ct, ct2, ret:="",msg
	
	texto:=strtran(alltrim(upper(texto))," ","")

	calculaChaveExpandida(chave)

	// Validação dos caracteres do bloco de texto
	msg = validaHexadecimal(texto)
	if !empty(msg)
		? "Erro no texto!!!"
		? msg
		quit
	endif
	
	// Carregando a matriz texto corrente:
	posic=1
	for ct:= 1 to 4
		for ct2:= 1 to 4
			textoCorrente[ct2,ct]:= hex_dec( substr(texto,posic,2) )
			posic+=2
		next
	next
	
	// decifragem:

		addRoundKey(11)	// insere chave
		shiftRowsInversa()
		subBytesInversa()

		for ct:= 10 to 2 step -1
			addRoundKey(ct)	// insere chave					
			mixColumnsInversa()
			shiftRowsInversa()
			subBytesInversa()
		next
		addRoundKey(ct)	// insere chave					

		for ct:= 1 to 4
			for ct2:= 1 to 4
				ret+= dec_hex(textoCorrente[ct2,ct]) // + " "
			next
		next

return alltrim(ret)

/*
___________________________________________________________________________________________________
FUNÇÃO mixColumnsInversa()
Faz a mistura dos bytes das colunas da matriz (Função Inversa)
___________________________________________________________________________________________________
*/ 

function mixColumnsInversa() 
local ct, temp:=array(4), v1, v2, mat:=array(4), linha

	for coluna:= 1 to 4
		for linha:= 1 to 4
			do case
				case linha == 1
					temp[1] = tabela0e[textoCorrente[1,coluna]+1]
					temp[2] = tabela0b[textoCorrente[2,coluna]+1]
					temp[3] = tabela0d[textoCorrente[3,coluna]+1]
					temp[4] = tabela09[textoCorrente[4,coluna]+1]
				case linha == 2
					temp[1] = tabela09[textoCorrente[1,coluna]+1]
					temp[2] = tabela0e[textoCorrente[2,coluna]+1]
					temp[3] = tabela0b[textoCorrente[3,coluna]+1]
					temp[4] = tabela0d[textoCorrente[4,coluna]+1]
				case linha == 3
					temp[1] = tabela0d[textoCorrente[1,coluna]+1]
					temp[2] = tabela09[textoCorrente[2,coluna]+1]
					temp[3] = tabela0e[textoCorrente[3,coluna]+1]
					temp[4] = tabela0b[textoCorrente[4,coluna]+1]
				case linha == 4
					temp[1] = tabela0b[textoCorrente[1,coluna]+1]
					temp[2] = tabela0d[textoCorrente[2,coluna]+1]
					temp[3] = tabela09[textoCorrente[3,coluna]+1]
					temp[4] = tabela0e[textoCorrente[4,coluna]+1]
			endcase

			v1 = fxor(temp[1],temp[2])
			v2 = fxor(temp[3],temp[4])
			mat[linha] = fxor(v1,v2)
		next

		for ct:= 1 to 4
			textoCorrente[ct,coluna]=mat[ct]
		next
	next
	
return NIL

/*
___________________________________________________________________________________________________
FUNÇÃO mixColumns()
Faz a mistura dos bytes das colunas da matriz
___________________________________________________________________________________________________
*/ 

function mixColumns() 
local ct, temp:=array(4), v1, v2, mat:=array(4), linha

	for coluna:= 1 to 4
		for linha:= 1 to 4
			do case
				case linha == 1
					temp[1] = tabela02[textoCorrente[1,coluna]+1]
					temp[2] = tabela03[textoCorrente[2,coluna]+1]
					temp[3] = textoCorrente[3,coluna]
					temp[4] = textoCorrente[4,coluna]
				case linha == 2
					temp[1] = textoCorrente[1,coluna]
					temp[2] = tabela02[textoCorrente[2,coluna]+1]
					temp[3] = tabela03[textoCorrente[3,coluna]+1]
					temp[4] = textoCorrente[4,coluna]
				case linha == 3
					temp[1] = textoCorrente[1,coluna]
					temp[2] = textoCorrente[2,coluna]
					temp[3] = tabela02[textoCorrente[3,coluna]+1]
					temp[4] = tabela03[textoCorrente[4,coluna]+1]
				case linha == 4
					temp[1] = tabela03[textoCorrente[1,coluna]+1]
					temp[2] = textoCorrente[2,coluna]
					temp[3] = textoCorrente[3,coluna]
					temp[4] = tabela02[textoCorrente[4,coluna]+1]
			endcase

			v1 = fxor(temp[1],temp[2])
			v2 = fxor(temp[3],temp[4])
			mat[linha] = fxor(v1,v2)
		next

		for ct:= 1 to 4
			textoCorrente[ct,coluna]=mat[ct]
		next
	next
	
return NIL

/*
___________________________________________________________________________________________________
FUNÇÃO subBytesInversa()
Faz a alteração do byte utilizando a sbox inversa 
___________________________________________________________________________________________________
*/ 
function subBytesInversa()
local ct, ct2

	for ct:= 1 to 4
		for ct2:= 1 to 4
			textoCorrente[ct2,ct]:=sbox_inversa[textoCorrente[ct2,ct]+1] 
		next
	next

return NIL

/*
___________________________________________________________________________________________________
FUNÇÃO subBytes()
Faz a alteração do byte utilizando a sbox padrão do algoritmo
___________________________________________________________________________________________________
*/ 

function subBytes()
local ct, ct2

	for ct:= 1 to 4
		for ct2:= 1 to 4
			textoCorrente[ct2,ct]:=sbox[textoCorrente[ct2,ct]+1] 
		next
	next

return NIL

/*
___________________________________________________________________________________________________
FUNÇÃO shiftRows()
Faz o deslocamento das linhas em cada estado da matriz
___________________________________________________________________________________________________
*/ 

function shiftRows()
local ct, ct2, tmp:=array(2)

	// 2ª linha:
		tmp[1] := textoCorrente[2,1]
		textoCorrente[2,1]:=textoCorrente[2,2]
		textoCorrente[2,2]:=textoCorrente[2,3]
		textoCorrente[2,3]:=textoCorrente[2,4]
		textoCorrente[2,4]:=tmp[1]

	// 3ª linha:
		tmp[1] := textoCorrente[3,1]
		tmp[2] := textoCorrente[3,2]
		textoCorrente[3,1]:=textoCorrente[3,3]
		textoCorrente[3,2]:=textoCorrente[3,4]
		textoCorrente[3,3]:=tmp[1]
		textoCorrente[3,4]:=tmp[2]

	// 4ª linha:
		tmp[1] := textoCorrente[4,4]
		textoCorrente[4,4]:=textoCorrente[4,3]
		textoCorrente[4,3]:=textoCorrente[4,2]
		textoCorrente[4,2]:=textoCorrente[4,1]
		textoCorrente[4,1]:=tmp[1]

return NIL


/*
___________________________________________________________________________________________________
FUNÇÃO shiftRowsInversa()
Faz o deslocamento das linhas em cada estado da matriz (Função Inversa)
___________________________________________________________________________________________________
*/ 

function shiftRowsInversa()
local ct, ct2, tmp:=array(2)

	// 2ª linha:
		tmp[1] := textoCorrente[2,4]
		textoCorrente[2,4]:=textoCorrente[2,3]
		textoCorrente[2,3]:=textoCorrente[2,2]
		textoCorrente[2,2]:=textoCorrente[2,1]
		textoCorrente[2,1]:=tmp[1]

	// 3ª linha:
		tmp[1] := textoCorrente[3,1]
		tmp[2] := textoCorrente[3,2]
		textoCorrente[3,1]:=textoCorrente[3,3]
		textoCorrente[3,2]:=textoCorrente[3,4]
		textoCorrente[3,3]:=tmp[1]
		textoCorrente[3,4]:=tmp[2]

	// 4ª linha:
		tmp[1] := textoCorrente[4,1]
		textoCorrente[4,1]:=textoCorrente[4,2]
		textoCorrente[4,2]:=textoCorrente[4,3]
		textoCorrente[4,3]:=textoCorrente[4,4]
		textoCorrente[4,4]:=tmp[1]

return NIL

/*
___________________________________________________________________________________________________
FUNÇÃO addRoundKey()
Insere a chave de 128 bits no bloco de texto corrente
___________________________________________________________________________________________________
*/ 
function addRoundKey(nRound)
local ct, ct2

	for ct:= 1 to 4
		for ct2:= 1 to 4
			textoCorrente[ct2,ct]:=fxor(textoCorrente[ct2,ct],chaveCorrente[nRound,ct2,ct])
		next
	next

return NIL

/*
___________________________________________________________________________________________________
FUNÇÃO calculaChaveExpandida()
Função de cálculo de escalonamento de chaves no AES-128
Parâmetro: Chave no formato hexadecimal
___________________________________________________________________________________________________
*/ 

function calculaChaveExpandida(chave)
	local ct, ct2, ct3, posic, temp := array(4), vtemp, chaveExpandida:=array(11)
	
	chave:=strtran(alltrim(upper(chave))," ","")

	for ct:= 1 to 11
		chaveExpandida[ct]:=""
	next

	// Verificando se a chave está no padrão correto
	msg = validaHexadecimal(chave)
	if !empty(msg)
		? "Erro na chave!!!"
		? msg
		quit
	endif

	chaveExpandida[1]:=chave

	posic=1
	for ct:= 1 to 4
		for ct2:= 1 to 4
			estadoChave[ct2,ct]:= hex_dec( substr(chaveExpandida[1],posic,2) )
			posic+=2
		next
	next

	for ct:= 2 to 11
		for ct2:= 1 to 4
			temp[ct2] = estadoChave[ct2,4]
		next

		// Operação RotWord()
		vtemp := temp[1]
		for ct2:= 1 to 3
			temp[ct2] = temp[ct2+1]
		next
		temp[4]=vtemp

		// Operação SubWord()
		for ct2:= 1 to 4
			temp[ct2] = sbox[temp[ct2]+1]
		next
	
		// Operação Rcon
		for ct2:= 1 to 4
			temp[ct2] = fxor(temp[ct2],rcon[ct-1,ct2])
		next

		// Operação XOR com subchaves do bloco anterior
		for ct3:= 1 to 4
			for ct2:= 1 to 4
				temp[ct2] = fxor(temp[ct2],estadoChave[ct2,ct3])
				chaveExpandida[ct] += dec_hex(temp[ct2])
			next
		next

		// Atualizando o estado atual das subchaves para a proxima rodada
		posic = 1
		for ct3:= 1 to 4
			for ct2:= 1 to 4
				estadoChave[ct2,ct3]:= hex_dec( substr(chaveExpandida[ct],posic,2) )
				posic+=2
			next
		next

	next

		// Preenchendo a matriz de chaves para ser usada em toda a rotina de cifragem ou decifragem

		for ct:= 1 to 11
			posic = 1
			for ct3:= 1 to 4
				for ct2:= 1 to 4
					chaveCorrente[ct,ct2,ct3]:= hex_dec( substr(chaveExpandida[ct],posic,2) )
					posic+=2
				next
			next
		next

return NIL

/*
___________________________________________________________________________________________________
FUNÇÃO IniciarAES()
Função para iniciar parâmetros necessários para realizar cifragem e decifragem
___________________________________________________________________________________________________
*/ 

function iniciarAES()
	public chaveCorrente:=array(16,4,4), textoCorrente:=array(4,4), sbox:=array(256), sbox_inversa:=array(256),;
		   rcon:=array(10,4), estadoChave:=array(4,4), tabela02:=array(256), tabela03:=array(256), tabela09:=array(256),;
			tabela0b:=array(256), tabela0d:=array(256), tabela0e:=array(256)

	sbox := { ;
		 99, 124, 119, 123, 242, 107, 111, 197,  48,   1, 103,  43, 254, 215, 171, 118, ;                                            
		202, 130, 201, 125, 250,  89,  71, 240, 173, 212, 162, 175, 156, 164, 114, 192, ;
		183, 253, 147,  38,  54,  63, 247, 204,  52, 165, 229, 241, 113, 216,  49,  21, ;
		  4, 199,  35, 195,  24, 150,   5, 154,   7,  18, 128, 226, 235,  39, 178, 117, ;
		  9, 131,  44,  26,  27, 110,  90, 160,  82,  59, 214, 179,  41, 227,  47, 132, ;
		 83, 209,   0, 237,  32, 252, 177,  91, 106, 203, 190,  57,  74,  76,  88, 207, ;
		208, 239, 170, 251,  67,  77,  51, 133,  69, 249,   2, 127,  80,  60, 159, 168, ;
		 81, 163,  64, 143, 146, 157,  56, 245, 188, 182, 218,  33,  16, 255, 243, 210, ;
		205,  12,  19, 236,  95, 151,  68,  23, 196, 167, 126,  61, 100,  93,  25, 115, ;
		 96, 129,  79, 220,  34,  42, 144, 136,  70, 238, 184,  20, 222,  94,  11, 219, ;
		224,  50,  58,  10,  73,   6,  36,  92, 194, 211, 172,  98, 145, 149, 228, 121, ;
		231, 200,  55, 109, 141, 213,  78, 169, 108,  86, 244, 234, 101, 122, 174,   8, ;
		186, 120,  37,  46,  28, 166, 180, 198, 232, 221, 116,  31,  75, 189, 139, 138, ;
		112,  62, 181, 102,  72,   3, 246,  14,  97,  53,  87, 185, 134, 193,  29, 158, ;
		225, 248, 152,  17, 105, 217, 142, 148, 155,  30, 135, 233, 206,  85,  40, 223, ;
		140, 161, 137,  13, 191, 230,  66, 104,  65, 153,  45,  15, 176,  84, 187,  22  ; 
	}

	sbox_inversa := { ;
		 82,   9, 106, 213,  48,  54, 165,  56, 191,  64, 163, 158, 129, 243, 215, 251, ;
		124, 227,  57, 130, 155,  47, 255, 135,  52, 142,  67,  68, 196, 222, 233, 203, ;
		 84, 123, 148,  50, 166, 194,  35,  61, 238,  76, 149,  11,  66, 250, 195,  78, ;
		  8,  46, 161, 102,  40, 217,  36, 178, 118,  91, 162,  73, 109, 139, 209,  37, ;
		114, 248, 246, 100, 134, 104, 152,  22, 212, 164,  92, 204,  93, 101, 182, 146, ;
		108, 112,  72,  80, 253, 237, 185, 218,  94,  21,  70,  87, 167, 141, 157, 132, ;
		144, 216, 171,   0, 140, 188, 211,  10, 247, 228,  88,   5, 184, 179,  69,   6, ;
		208,  44,  30, 143, 202,  63,  15,   2, 193, 175, 189,   3,   1,  19, 138, 107, ;
		 58, 145,  17,  65,  79, 103, 220, 234, 151, 242, 207, 206, 240, 180, 230, 115, ;
		150, 172, 116,  34, 231, 173,  53, 133, 226, 249,  55, 232,  28, 117, 223, 110, ;
		 71, 241,  26, 113,  29,  41, 197, 137, 111, 183,  98,  14, 170,  24, 190,  27, ;
		252,  86,  62,  75, 198, 210, 121,  32, 154, 219, 192, 254, 120, 205,  90, 244, ;
		 31, 221, 168,  51, 136,   7, 199,  49, 177,  18,  16,  89,  39, 128, 236,  95, ;
		 96,  81, 127, 169,  25, 181,  74,  13,  45, 229, 122, 159, 147, 201, 156, 239, ;
		160, 224,  59,  77, 174,  42, 245, 176, 200, 235, 187,  60, 131,  83, 153,  97, ;
		 23,  43,   4, 126, 186, 119, 214,  38, 225, 105,  20,  99,  85,  33,  12, 125  ;
	}

	tabela02 := { ;
		  0,   2,   4,   6,   8,  10,  12,  14,  16,  18,  20,  22,  24,  26,  28,  30, ;                                            
		 32,  34,  36,  38,  40,  42,  44,  46,  48,  50,  52,  54,  56,  58,  60,  62, ;
		 64,  66,  68,  70,  72,  74,  76,  78,  80,  82,  84,  86,  88,  90,  92,  94, ;
		 96,  98, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122, 124, 126, ;
		128, 130, 132, 134, 136, 138, 140, 142, 144, 146, 148, 150, 152, 154, 156, 158, ;
		160, 162, 164, 166, 168, 170, 172, 174, 176, 178, 180, 182, 184, 186, 188, 190, ;
		192, 194, 196, 198, 200, 202, 204, 206, 208, 210, 212, 214, 216, 218, 220, 222, ;
		224, 226, 228, 230, 232, 234, 236, 238, 240, 242, 244, 246, 248, 250, 252, 254, ;
		 27,  25,  31,  29,  19,  17,  23,  21,  11,   9,  15,  13,   3,   1,   7,   5, ;
		 59,  57,  63,  61,  51,  49,  55,  53,  43,  41,  47,  45,  35,  33,  39,  37, ;
		 91,  89,  95,  93,  83,  81,  87,  85,  75,  73,  79,  77,  67,  65,  71,  69, ;
		123, 121, 127, 125, 115, 113, 119, 117, 107, 105, 111, 109,  99,  97, 103, 101, ;
		155, 153, 159, 157, 147, 145, 151, 149, 139, 137, 143, 141, 131, 129, 135, 133, ;
		187, 185, 191, 189, 179, 177, 183, 181, 171, 169, 175, 173, 163, 161, 167, 165, ;
		219, 217, 223, 221, 211, 209, 215, 213, 203, 201, 207, 205, 195, 193, 199, 197, ;
		251, 249, 255, 253, 243, 241, 247, 245, 235, 233, 239, 237, 227, 225, 231, 229  ;
	}

	tabela03 := { ;
		  0,   3,   6,   5,  12,  15,  10,   9,  24,  27,  30,  29,  20,  23,  18,  17, ;                                            
		 48,  51,  54,  53,  60,  63,  58,  57,  40,  43,  46,  45,  36,  39,  34,  33, ;
		 96,  99, 102, 101, 108, 111, 106, 105, 120, 123, 126, 125, 116, 119, 114, 113, ;
		 80,  83,  86,  85,  92,  95,  90,  89,  72,  75,  78,  77,  68,  71,  66,  65, ;
		192, 195, 198, 197, 204, 207, 202, 201, 216, 219, 222, 221, 212, 215, 210, 209, ;
		240, 243, 246, 245, 252, 255, 250, 249, 232, 235, 238, 237, 228, 231, 226, 225, ;
		160, 163, 166, 165, 172, 175, 170, 169, 184, 187, 190, 189, 180, 183, 178, 177, ;
		144, 147, 150, 149, 156, 159, 154, 153, 136, 139, 142, 141, 132, 135, 130, 129, ;
		155, 152, 157, 158, 151, 148, 145, 146, 131, 128, 133, 134, 143, 140, 137, 138, ;
		171, 168, 173, 174, 167, 164, 161, 162, 179, 176, 181, 182, 191, 188, 185, 186, ;
		251, 248, 253, 254, 247, 244, 241, 242, 227, 224, 229, 230, 239, 236, 233, 234, ;
		203, 200, 205, 206, 199, 196, 193, 194, 211, 208, 213, 214, 223, 220, 217, 218, ;
		 91,  88,  93,  94,  87,  84,  81,  82,  67,  64,  69,  70,  79,  76,  73,  74, ;
		107, 104, 109, 110, 103, 100,  97,  98, 115, 112, 117, 118, 127, 124, 121, 122, ;
		 59,  56,  61,  62,  55,  52,  49,  50,  35,  32,  37,  38,  47,  44,  41,  42, ;
		 11,   8,  13,  14,   7,   4,   1,   2,  19,  16,  21,  22,  31,  28,  25,  26  ;
	}

	tabela09 := { ;
		  0,   9,  18,  27,  36,  45,  54,  63,  72,  65,  90,  83, 108, 101, 126, 119, ;                                            
		144, 153, 130, 139, 180, 189, 166, 175, 216, 209, 202, 195, 252, 245, 238, 231, ;
		 59,  50,  41,  32,  31,  22,  13,   4, 115, 122,  97, 104,  87,  94,  69,  76, ;
		171, 162, 185, 176, 143, 134, 157, 148, 227, 234, 241, 248, 199, 206, 213, 220, ;
		118, 127, 100, 109,  82,  91,  64,  73,  62,  55,  44,  37,  26,  19,   8,   1, ;
		230, 239, 244, 253, 194, 203, 208, 217, 174, 167, 188, 181, 138, 131, 152, 145, ;
		 77,  68,  95,  86, 105,  96, 123, 114,   5,  12,  23,  30,  33,  40,  51,  58, ;
		221, 212, 207, 198, 249, 240, 235, 226, 149, 156, 135, 142, 177, 184, 163, 170, ;
		236, 229, 254, 247, 200, 193, 218, 211, 164, 173, 182, 191, 128, 137, 146, 155, ;
		124, 117, 110, 103,  88,  81,  74,  67,  52,  61,  38,  47,  16,  25,   2,  11, ;
		215, 222, 197, 204, 243, 250, 225, 232, 159, 150, 141, 132, 187, 178, 169, 160, ;
		 71,  78,  85,  92,  99, 106, 113, 120,  15,   6,  29,  20,  43,  34,  57,  48, ;
		154, 147, 136, 129, 190, 183, 172, 165, 210, 219, 192, 201, 246, 255, 228, 237, ;
		 10,   3,  24,  17,  46,  39,  60,  53,  66,  75,  80,  89, 102, 111, 116, 125, ;
		161, 168, 179, 186, 133, 140, 151, 158, 233, 224, 251, 242, 205, 196, 223, 214, ;
		 49,  56,  35,  42,  21,  28,   7,  14, 121, 112, 107,  98,  93,  84,  79,  70  ;
	}

	tabela0b := { ;
		  0,  11,  22,  29,  44,  39,  58,  49,  88,  83,  78,  69, 116, 127,  98, 105, ;                                            
		176, 187, 166, 173, 156, 151, 138, 129, 232, 227, 254, 245, 196, 207, 210, 217, ;
		123, 112, 109, 102,  87,  92,  65,  74,  35,  40,  53,  62,  15,   4,  25,  18, ;
		203, 192, 221, 214, 231, 236, 241, 250, 147, 152, 133, 142, 191, 180, 169, 162, ;
		246, 253, 224, 235, 218, 209, 204, 199, 174, 165, 184, 179, 130, 137, 148, 159, ;
		 70,  77,  80,  91, 106,  97, 124, 119,  30,  21,   8,   3,  50,  57,  36,  47, ;
		141, 134, 155, 144, 161, 170, 183, 188, 213, 222, 195, 200, 249, 242, 239, 228, ;
		 61,  54,  43,  32,  17,  26,   7,  12, 101, 110, 115, 120,  73,  66,  95,  84, ;
		247, 252, 225, 234, 219, 208, 205, 198, 175, 164, 185, 178, 131, 136, 149, 158, ;
		 71,  76,  81,  90, 107,  96, 125, 118,  31,  20,   9,   2,  51,  56,  37,  46, ;
		140, 135, 154, 145, 160, 171, 182, 189, 212, 223, 194, 201, 248, 243, 238, 229, ;
		 60,  55,  42,  33,  16,  27,   6,  13, 100, 111, 114, 121,  72,  67,  94,  85, ;
		  1,  10,  23,  28,  45,  38,  59,  48,  89,  82,  79,  68, 117, 126,  99, 104, ;
		177, 186, 167, 172, 157, 150, 139, 128, 233, 226, 255, 244, 197, 206, 211, 216, ;
		122, 113, 108, 103,  86,  93,  64,  75,  34,  41,  52,  63,  14,   5,  24,  19, ;
		202, 193, 220, 215, 230, 237, 240, 251, 146, 153, 132, 143, 190, 181, 168, 163  ;
	}

	tabela0d := { ;
		  0,  13,  26,  23,  52,  57,  46,  35, 104, 101, 114, 127,  92,  81,  70,  75, ;                                            
		208, 221, 202, 199, 228, 233, 254, 243, 184, 181, 162, 175, 140, 129, 150, 155, ;
		187, 182, 161, 172, 143, 130, 149, 152, 211, 222, 201, 196, 231, 234, 253, 240, ;
		107, 102, 113, 124,  95,  82,  69,  72,   3,  14,  25,  20,  55,  58,  45,  32, ;
		109,  96, 119, 122,  89,  84,  67,  78,   5,   8,  31,  18,  49,  60,  43,  38, ;
		189, 176, 167, 170, 137, 132, 147, 158, 213, 216, 207, 194, 225, 236, 251, 246, ;
		214, 219, 204, 193, 226, 239, 248, 245, 190, 179, 164, 169, 138, 135, 144, 157, ;
		  6,  11,  28,  17,  50,  63,  40,  37, 110,  99, 116, 121,  90,  87,  64,  77, ;
		218, 215, 192, 205, 238, 227, 244, 249, 178, 191, 168, 165, 134, 139, 156, 145, ;
		 10,   7,  16,  29,  62,  51,  36,  41,  98, 111, 120, 117,  86,  91,  76,  65, ;
		 97, 108, 123, 118,  85,  88,  79,  66,   9,   4,  19,  30,  61,  48,  39,  42, ;
		177, 188, 171, 166, 133, 136, 159, 146, 217, 212, 195, 206, 237, 224, 247, 250, ;
		183, 186, 173, 160, 131, 142, 153, 148, 223, 210, 197, 200, 235, 230, 241, 252, ;
		103, 106, 125, 112,  83,  94,  73,  68,  15,   2,  21,  24,  59,  54,  33,  44, ;
		 12,   1,  22,  27,  56,  53,  34,  47, 100, 105, 126, 115,  80,  93,  74,  71, ;
		220, 209, 198, 203, 232, 229, 242, 255, 180, 185, 174, 163, 128, 141, 154, 151  ;
	}

	tabela0e := { ;
		  0,  14,  28,  18,  56,  54,  36,  42, 112, 126, 108,  98,  72,  70,  84,  90, ;                                            
		224, 238, 252, 242, 216, 214, 196, 202, 144, 158, 140, 130, 168, 166, 180, 186, ;
		219, 213, 199, 201, 227, 237, 255, 241, 171, 165, 183, 185, 147, 157, 143, 129, ;
		 59,  53,  39,  41,   3,  13,  31,  17,  75,  69,  87,  89, 115, 125, 111,  97, ;
		173, 163, 177, 191, 149, 155, 137, 135, 221, 211, 193, 207, 229, 235, 249, 247, ;
		 77,  67,  81,  95, 117, 123, 105, 103,  61,  51,  33,  47,   5,  11,  25,  23, ;
		118, 120, 106, 100,  78,  64,  82,  92,   6,   8,  26,  20,  62,  48,  34,  44, ;
		150, 152, 138, 132, 174, 160, 178, 188, 230, 232, 250, 244, 222, 208, 194, 204, ;
		 65,  79,  93,  83, 121, 119, 101, 107,  49,  63,  45,  35,   9,   7,  21,  27, ;
		161, 175, 189, 179, 153, 151, 133, 139, 209, 223, 205, 195, 233, 231, 245, 251, ;
		154, 148, 134, 136, 162, 172, 190, 176, 234, 228, 246, 248, 210, 220, 206, 192, ;
		122, 116, 102, 104,  66,  76,  94,  80,  10,   4,  22,  24,  50,  60,  46,  32, ;
		236, 226, 240, 254, 212, 218, 200, 198, 156, 146, 128, 142, 164, 170, 184, 182, ;
		 12,   2,  16,  30,  52,  58,  40,  38, 124, 114,  96, 110,  68,  74,  88,  86, ;
		 55,  57,  43,  37,  15,   1,  19,  29,  71,  73,  91,  85, 127, 113,  99, 109, ;
		215, 217, 203, 197, 239, 225, 243, 253, 167, 169, 187, 181, 159, 145, 131, 141  ;
	}

	rcon := {;
		{  1,   0,   0,   0 },;
		{  2,   0,   0,   0 },;
		{  4,   0,   0,   0 },;
		{  8,   0,   0,   0 },;
		{ 16,   0,   0,   0 },;
		{ 32,   0,   0,   0 },;
		{ 64,   0,   0,   0 },;
		{128,   0,   0,   0 },;
		{ 27,   0,   0,   0 },;
		{ 54,   0,   0,   0 } ;
	}

return NIL

/*
___________________________________________________________________________________________________
FUNÇÃO FXOR() 
Faz o XOR entre dois bytes (números no intervalo 0 <= num <= 255)
___________________________________________________________________________________________________
*/ 

function fxor(n1,n2)
	local valor, ret 

	valor:= ft_byteXOR(hb_Bchar(n1), hb_Bchar(n2))
	ret := hb_Bcode(valor)

return ret

/*
___________________________________________________________________________________________________
FUNÇÃO HEX_DEC() 
Converte um número hexadecimal em um número decimal (números no intervalo 0 <= num <= 255)
___________________________________________________________________________________________________
*/ 

function hex_dec(num)
	local ret

	num = upper(alltrim(num))
	ret:=int(hexatodec(num))

return ret

/*
___________________________________________________________________________________________________
FUNÇÃO DEC_HEX() 
	converte decimal para hexadecimal (0 até 255)
___________________________________________________________________________________________________
*/ 
function dec_hex(num)
local valor, ret

	valor:=dectohexa(num)
	ret := replicate("0",2-len(valor)) + valor

return ret

/*
___________________________________________________________________________________________________
FUNÇÃO validaHexadecimal() 
	verifica se uma string é hexadecimal e tem tamanho 32
___________________________________________________________________________________________________
*/ 
function validaHexadecimal(cadeia_texto)
local ret:="", ct

		cadeia_texto:= strtran(upper(alltrim(cadeia_texto))," ","")

		if len(cadeia_texto) <> 32
			ret := "A string deve ter 32 caracteres hexadecimais!"
		endif

		for ct:= 1 to 32
			if !(substr(cadeia_texto,ct,1) $ "0123456789ABCDEF")
				ret +=  " | A string contém caracteres inválidos! Caracteres válidos: 0123456789ABCDEF"
			endif
		next

return ret

/*
___________________________________________________________________________________________________
FUNÇÃO converteTextoParaHexadecimal() 
	Converte uma string de 16 bytes em um conjunto hexadecimal com 32 elementos
___________________________________________________________________________________________________
*/ 
function converteTextoParaHexadecimal(texto)
local ret:="", ct, tam:=len(texto)

		if tam > 16
			? "O texto pode conter até 16 caracteres -> tamanho do bloco 128 bits!"
			quit
		elseif tam < 16
			texto := texto + replicate(" ",16-tam)
		endif

		for ct:= 1 to 16
			ret +=  dec_hex ( asc( substr(texto,ct,1) ) )
		next

return ret

/*
___________________________________________________________________________________________________
FUNÇÃO converteHexadecimalParaTexto() 
	Converte uma string hexadecimal de 32 elementos em uma string
___________________________________________________________________________________________________
*/ 
function converteHexadecimalParaTexto(texto)
local ret:="", ct, tam:=len(texto), msg

		texto:= strtran(upper(alltrim(texto))," ","")

		msg = validaHexadecimal(texto)
		if !empty(msg)
			? "Erro na entrada Hexadecimal!!!"
			? msg
			quit
		endif

		for ct:= 1 to 32 step 2
			ret+= chr( hex_dec(substr(texto,ct,2)) )
		next

return ret

/*
___________________________________________________________________________________________________
FUNÇÃO converteHexadecimalParaBase64() 
	Converte uma string hexadecimal de qualquer tamanho para uma string base64
___________________________________________________________________________________________________
*/ 
function converteHexadecimalParaBase64(texto)
local ret:="", ct, acumula:=""

		texto:= strtran(upper(alltrim(texto))," ","")
		tam:=len(texto)

		if tam%2 <> 0
			? "Tamanho da string hexadecimal inválido: deve ser múltiplo de 2!"
			quit
		endif

		for ct:= 1 to tam
			if !( substr(texto,ct,1) $ "0123456789ABCDEF" )
				? "Erro no formato da string hexadecimal!"
				quit
			endif
		next

		for ct:= 1 to tam step 2
			acumula+= chr( hex_dec(substr(texto,ct,2)) )
		next

		ret := hb_base64encode(acumula)

return ret

/*
___________________________________________________________________________________________________
FUNÇÃO converteBase64ParaHexadecimal() 
	Converte uma string em base64 para uma string Hexadecimal
___________________________________________________________________________________________________
*/ 
function converteBase64ParaHexadecimal(texto)
local ret:="", ct

		texto:= hb_base64decode(texto)
		tam:=len(texto)

		for ct:= 1 to tam
			ret+= dec_hex ( asc(substr(texto,ct,1)) )
		next

return ret

// =================================================
function ylib_iniciar()

	REQUEST HB_LANG_PT
	// REQUEST HB_CODEPAGE_UTF8EX
	REQUEST HB_CODEPAGE_UTF8
	HB_LANGSELECT( 'PT' )
	// HB_CDPSELECT( "UTF8EX" )
	HB_CDPSELECT( "UTF8" )		

	set date french
	set century on
	set scoreboard off
	set cursor off
	setblink(.f.)
	set confirm on	
	setmode(32,125)
	set message to 32 center
	set wrap On

    REQUEST DBFCDX

return nil


AES - Advanced Encryption Standard - Criptografia

Enviado: 09 Mai 2016 14:18
por alxsts
Olá!

Parabéns Yugi! Grato por compartilhar.

Para quem precisar do algoritmo SHA1, existe a função hb_SHA1(), tanto no Harbour quanto no xHarbour.

EncriptarAESSHA1

AES - Advanced Encryption Standard - Criptografia

Enviado: 30 Out 2017 10:41
por maicoarmany
Ola estou fazendo um trabalho sobre criptografia, não entendo de programação, sou da matemática, então estou calculando a mão e com uso do excel, porem após dias calculando devo ter errado alguma conta então eu gostaria de saber se este teu código fornece todos valores intermediários como as 10 sub-chaves e as matrizes após cada transformação. No meu exemplo é apenas 1 bloco 128 e uma chave 128. Se puder me ajudar agradeço.

AES - Advanced Encryption Standard - Criptografia

Enviado: 15 Nov 2018 16:23
por fasiferrari
yugi386,
Eu vi suas funções, mas vi que você pensou em fazer apenas o modo de 128 bits, como você também pode fazer para 192 e 256.
obrigado
desculpe pelo meu portugues (ja traduzi com google)

AES - Advanced Encryption Standard - Criptografia

Enviado: 16 Nov 2018 17:51
por yugi386
Saudações!

De fato o código que escrevi permite criptografar e decodificar apenas com chave de 128 bits.
Fiz o complemento do código que agora permite criptografar e decodificar texto e arquivos com chaves de 128, 192 e 256 bits.
O código completo segue em anexo.

O texto (strings) são criptografados em modo ECB e os arquivos em modo CBC.

Att,

Yugi