AES - Advanced Encryption Standard - Criptografia

Aqui você poderá oferecer suas Contribuições, Dicas e Tutoriais (Texto ou Vídeo) que sejam de interesse de todos.

Moderador: Moderadores

yugi386
Usuário Nível 2
Usuário Nível 2
Mensagens: 82
Registrado em: 24 Jul 2008 10:36
Localização: Minas Gerais

AES - Advanced Encryption Standard - Criptografia

Mensagem 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

Anexos
aes.zip
(343.9 KiB) Baixado 295 vezes
alxsts
Colaborador
Colaborador
Mensagens: 3092
Registrado em: 12 Ago 2008 15:50
Localização: São Paulo-SP-Brasil

AES - Advanced Encryption Standard - Criptografia

Mensagem 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
[]´s
Alexandre Santos (AlxSts)
maicoarmany
Usuário Nível 1
Usuário Nível 1
Mensagens: 1
Registrado em: 30 Out 2017 10:34
Localização: santa maria/rs

AES - Advanced Encryption Standard - Criptografia

Mensagem 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.
fasiferrari
Usuário Nível 1
Usuário Nível 1
Mensagens: 3
Registrado em: 30 Abr 2012 18:27
Localização: italy

AES - Advanced Encryption Standard - Criptografia

Mensagem 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)
yugi386
Usuário Nível 2
Usuário Nível 2
Mensagens: 82
Registrado em: 24 Jul 2008 10:36
Localização: Minas Gerais

AES - Advanced Encryption Standard - Criptografia

Mensagem 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
Anexos
aes.zip
AES 128, 192 e 256 bits (Código completo para criptografar strings e arquivos)
(346.22 KiB) Baixado 255 vezes
Editado pela última vez por Itamar M. Lins Jr. em 16 Abr 2025 21:46, em um total de 1 vez.
Razão: O presente tópico foi movido da seção Harbour. Esse local é mais apropriado.
Responder