finalizando trab 2

This commit is contained in:
José Henrique 2023-09-12 11:21:31 -03:00
parent 9fafd82b5c
commit 428122f04e
4 changed files with 160 additions and 97 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
*.dat
__pycache__

View File

@ -1,88 +1,76 @@
from hashlib import sha256 from hashlib import sha256
import localtoken import localtoken
import os
''' import time
Gerador:
Primeira vez criar
um usuário
uma senha semente (Senha igual a registrada no servidor, senha principal)
Um salt (o mesmo do Aplicativo)
uma senha local (Senha para acesso ao gerador de senhas somente)
Próximas vezes
Digitar usuário e a senha local, se correto continua.
Quando requisitado gera uma senha(Token).
(algoritmo gerador de senhas)
A senha (Token) deve ser gerada a partir da hash da senha semente do usuário (diferente da senha do usuário).
O aluno deve propor uma variante do algoritmo OTP de Lamport, visto em aula.
Este algoritmo deve levar em consideração o tempo (data hora minuto).
As senhas devem ter validade de no máximo um minuto e podem ser usadas uma única vez.(Fazer uma lista de senhas para ser usada no minuto. Ex.lista com 5 senhas para o minuto solicitado)
somente gerar lista de senhas para o minuto solicitado.
Servidor:
Quando acessado usa o mesmo algoritmo gerador de senhas anterior. Mas em instância separada.
A lista de senha gerada será a mesma nas duas partes, apesar de estarem em aplicativos separados e sem comunicação.
Verifica o usuário e se senha digitada esta na lista gerada e não foi usada e nem invalidada.
nesta caso apresenta Chave válida.
Atenção:
As senhas devem ter validade de no máximo um minuto e podem ser usadas uma única vez.
Senhas são geradas a partir de outras senhas, e se for usada uma chave todas as chaves geradas pela mesma devem ser invalidadas.
Se o cliente digitar uma senha válida o servidor aceita, caso contrario retorna mensagem de erro.
'''
USER = ''
LOCAL_PASSWORD = ''
SEED_PASSWORD = ''
SALT = ''
def check_setup():
try:
with open('gerador.dat', 'r', newline='') as setup:
lines = setup.readlines()
if len(lines) != 4:
return False
USER = lines[0]
LOCAL_PASSWORD = lines[1]
SEED_PASSWORD = lines[2]
SALT = lines[3]
return True
except:
init_setup()
return True
def init_setup(): def init_setup():
with open('gerador.dat', 'w', newline='') as setup: with open('gerador.dat', 'a', newline='') as setup:
user = input('Digite o usuário: ') user = input('Digite o usuário: ')
local_password = sha256(input('Digite a senha local: ').encode('utf-8')).hexdigest() local_password = sha256(input('Digite a senha local: ').encode('utf-8')).hexdigest()
seed_password = sha256(input('Digite a senha semente: ').encode('utf-8')).hexdigest() seed_password = sha256(input('Digite a senha semente: ').encode('utf-8')).hexdigest()
salt = sha256(input('Digite o salt: ').encode('utf-8')).hexdigest() salt = input('Digite o salt: ')
setup.write(user + '\n') salted_password = localtoken.get_salted_password(seed_password, salt)
setup.write(local_password + '\n')
setup.write(seed_password + '\n')
setup.write(salt)
def check_password(): line = f'{user},{local_password},{salted_password}\n'
local_password = sha256(input('Digite a senha local: ').encode('utf-8')).hexdigest() setup.write(line)
if local_password == LOCAL_PASSWORD:
return True print(f'Usuário [{user}] registrado com sucesso!')
else:
return False
def generate_token(): def generate_token():
token = localtoken.generate_token(SEED_PASSWORD, SALT) user = input('Digite o usuário: ')
print('Token gerado: ' + token[:8]) local_password = sha256(input('Digite a senha local: ').encode('utf-8')).hexdigest()
salted_password = ''
with open('gerador.dat', 'r', newline='') as setup:
for line in setup:
line = line.replace('\n', '')
def main(): if line.split(',')[0] == user and line.split(',')[1] == local_password:
if check_setup(): salted_password = line.split(',')[2]
if check_password(): break
input('Pressione alguma tecla para gerar uma senha...')
generate_token()
else: else:
print('Usuário ou senha incorretos!') print('Usuário ou senha incorretos!')
else: return
print('Erro ao verificar setup!')
loop_token(user, salted_password)
def loop_token(user, salted_password):
while True:
print(f'Gerando token para [{user}]...')
tokens = [localtoken.generate_token(salted_password)]
for i in range(4):
tokens.append(localtoken.generate_token(tokens[-1]))
for token in tokens:
print(token[:8])
# sleep until next minute
time.sleep(60 - time.time() % 60 + 1)
# clear console
os.system('cls' if os.name == 'nt' else 'clear')
def main():
while True:
print('Selecione uma opção:')
print('1 - Registrar usuário')
print('2 - Gerar token')
print('0 - Sair')
option = input('Opção: ')
if option == '1':
init_setup()
elif option == '2':
generate_token()
elif option == '0':
exit()
def exit():
print('Saindo...')
quit()
if __name__ == '__main__': if __name__ == '__main__':
if not os.path.exists('gerador.dat'):
open('gerador.dat', 'w').close()
main() main()

View File

@ -1,7 +1,29 @@
from hashlib import sha256 from hashlib import sha256
import time import time
# password = hashed password # token = hashed password + hashed salt
def generate_token(password, salt): def generate_token(token):
time = time.strftime('%d%m%Y%H%M') time = get_timestamp()
token = sha256((password + salt + time).encode('utf-8')).hexdigest() token = sha256((token + time).encode('utf-8')).hexdigest()
return token
# password = hashed seed password
# salt = hashed salt
def get_salted_password(password, salt):
return sha256((password + salt).encode('utf-8')).hexdigest()
def validate_token(salted_password, token, n=5):
time = get_timestamp()
tokens = []
for i in range(n):
last = tokens[-1] if len(tokens) > 0 else salted_password
tokens.append(generate_token(last))
if token[:8] == tokens[-1][:8]:
return True, i
return False, -1
def get_timestamp():
return time.strftime('%d%m%Y%H%M')

View File

@ -1,34 +1,85 @@
from hashlib import sha256 from hashlib import sha256
import string
import localtoken import localtoken
import random
import os
''' def register_user():
Quando acessado usa o mesmo algoritmo gerador de senhas anterior. Mas em instância separada. user = input('Digite o usuário: ')
A lista de senha gerada será a mesma nas duas partes, apesar de estarem em aplicativos separados e sem comunicação. seed_password = sha256(input('Digite a senha: ').encode('utf-8')).hexdigest()
Verifica o usuário e se senha digitada esta na lista gerada e não foi usada e nem invalidada. salt = ''.join(random.choice(string.ascii_letters) for i in range(16))
nesta caso apresenta Chave válida. salt = sha256(salt.encode('utf-8')).hexdigest()
Atenção:
As senhas devem ter validade de no máximo um minuto e podem ser usadas uma única vez.
Senhas são geradas a partir de outras senhas, e se for usada uma chave todas as chaves geradas pela mesma devem ser invalidadas.
Se o cliente digitar uma senha válida o servidor aceita, caso contrario retorna mensagem de erro.
''' line = f'{user},{seed_password},{salt}\n'
with open('server.dat', 'a', newline='') as setup:
setup.write(line)
SALT = '' print(f'Usuário registrado com sucesso! Salt: [{salt}]')
PASSWORD = ''
def validate_token():
user = input('Digite o usuário: ')
token = input('Digite o token: ')
password = ''
salt = ''
with open('server.dat', 'r', newline='') as setup:
for line in setup:
if len(line) == 0:
continue
line = line.replace('\n', '')
if line.split(',')[0] == user:
password = line.split(',')[1]
salt = line.split(',')[2]
break
else:
print('Usuário incorreto!')
return
used_index = -1
used_timestamp = ''
with open('used_tokens.dat', 'r', newline='') as used_tokens:
for used_token in reversed(list(used_tokens)):
used_token = used_token.replace('\n', '')
if used_token.split(',')[0] == user:
used_index = int(used_token.split(',')[1])
used_timestamp = used_token.split(',')[2]
break
password = localtoken.get_salted_password(password, salt)
valid, index = localtoken.validate_token(password, token)
if valid:
if used_index <= index and used_timestamp == localtoken.get_timestamp():
print('Chave inválida (invalidada)!')
else:
print('Chave válida!')
with open('used_tokens.dat', 'a', newline='') as used_tokens:
line = f'{user},{index},{localtoken.get_timestamp()}'
used_tokens.write(line + '\n')
else:
print('Chave inválida!')
def main(): def main():
print('Servidor!')
SALT = sha256(input('Digite o salt: ').encode('utf-8')).hexdigest()
PASSWORD = sha256(input('Digite a senha: ').encode('utf-8')).hexdigest()
while True: while True:
token = input('Digite o token: ') print('Selecione uma opção:')
if localtoken.generate_token(PASSWORD, SALT)[:8] == token[:8]: print('1 - Registrar usuário')
print('Chave válida!') print('2 - Validar token')
else: print('0 - Sair')
print('Chave inválida!')
option = input('Digite a opção: ')
if option == '1':
register_user()
elif option == '2':
validate_token()
elif option == '0':
exit()
if __name__ == '__main__': if __name__ == '__main__':
if not os.path.exists('server.dat'):
open('server.dat', 'w').close()
if not os.path.exists('used_tokens.dat'):
open('used_tokens.dat', 'w').close()
main() main()