-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Initial commit: a working login function without a database
- Loading branch information
0 parents
commit f40fe3e
Showing
27 changed files
with
17,060 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
__pycache__ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
from . import User | ||
|
||
|
||
# Create users | ||
users = dict() | ||
user_map = dict() # reverse lookup from username to user ID(s) | ||
for u in ['mario', 'luigi', 'chiara' , 'jacopo', 'andrea', 'beatrice']: | ||
new_user = User.User(u, 'pwd') | ||
print('Created new user:', new_user, sep='\n') | ||
users[new_user] = False # not logged | ||
if u not in user_map.keys(): | ||
user_map[u] = [new_user.user_id] | ||
else: | ||
user_map[u].append(new_user.user_id) | ||
|
||
from flask import ( | ||
Blueprint, flash, g, redirect, render_template, request, session, url_for | ||
) | ||
|
||
blueprint = Blueprint('auth', __name__,url_prefix='/auth') | ||
|
||
@blueprint.route('/', methods=['GET']) | ||
@blueprint.route('/login', methods=['GET', 'POST']) | ||
def login(): | ||
print(request, request.get_data(as_text=True), sep='\n') | ||
error = None | ||
if request.method == 'POST': | ||
username = request.form['username'] | ||
pwd = request.form['pwd'] | ||
|
||
if (not username) or (not pwd): | ||
error = 'Username o password non specificata' | ||
else: | ||
if username not in user_map.keys(): | ||
error = 'Utente inesistente' | ||
found = False | ||
for user in users.keys(): | ||
if user.username == username and user.check_pwd(pwd): | ||
users[user] = True # set user to logged | ||
return redirect(url_for('chat.home_user', username=username)) | ||
if not found: | ||
error = 'Password errata' | ||
if error is not None: | ||
print(error) | ||
# store error to be shown | ||
flash(error) | ||
return render_template('login.html', error=error) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
from time import time | ||
|
||
class Chat: | ||
"""Defines a chat between two users. | ||
""" | ||
def __init__(self, user: str): | ||
self.recipient = user | ||
self.creation_tstamp = int(time.time()) | ||
self.messages = [] | ||
|
||
def add_message(data: str, timestamp): | ||
"""Adds a new message to this chat. | ||
""" | ||
self.messages.append(Msg.EncryptedMsg(data, timestamp)) | ||
def delete_message(target): | ||
"""Deletes a message from this chat. | ||
""" | ||
try: | ||
i = self.messages.index(target) | ||
del self.messages[i] | ||
except ValueError: | ||
print("Message", target, "not found") | ||
|
||
from flask import (Blueprint, request, render_template) | ||
|
||
blueprint = Blueprint('chat', __name__, url_prefix='/chats') | ||
|
||
@blueprint.route('/<username>', methods=['GET']) | ||
def home_user(username=None): | ||
return render_template('index.html', username=username) | ||
|
||
@blueprint.route('/<creator>/', methods=['GET']) | ||
# TODO: post | ||
def create_chat(creator): | ||
data = request.get_json() | ||
if data is not None: | ||
pass | ||
else: | ||
pass | ||
return "POSTed chat by " + creator | ||
|
||
|
||
@blueprint.route('/<creator>/<recipient>/', methods=['GET']) | ||
# TODO: delete | ||
def delete_chat(creator, recipient): | ||
return "DELETED chat between " + creator + " and " + recipient |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
class EncryptedMsg: | ||
def __init__(self, data: str, stamp: int): | ||
self.message = data | ||
self.timestamp = stamp | ||
|
||
from flask import Blueprint | ||
|
||
blueprint = Blueprint('msg', __name__, url_prefix='/msg') | ||
|
||
|
||
@blueprint.route('/<sender>/<receiver>/', methods=['GET']) | ||
def get_all_messages(sender, receiver): | ||
return f"GET all msg from {sender} to {receiver}" | ||
|
||
|
||
@blueprint.route('/<sender>/<receiver>/<int:msg_id>/', methods=['GET']) | ||
def get_message(sender, receiver, msg_id): | ||
return f"GET msg from {sender} to {receiver}: ID = {msg_id}" | ||
|
||
|
||
@blueprint.route('/<sender>/<receiver>/', methods=['GET']) | ||
# TODO: post | ||
def send_message(sender, receiver): | ||
return f"POSTed msg from {sender} to {receiver}" | ||
|
||
|
||
@blueprint.route('/<sender>/<receiver>/<int:msg_id>', methods=['GET']) | ||
# TODO: put | ||
def edit_message(sender, receiver, msg_id): | ||
return f"PUTed msg from {sender} to {receiver}: {msg_id}" | ||
|
||
|
||
@blueprint.route('/<sender>/<receiver>/<int:msg_id>', methods=['GET']) | ||
# TODO: delete | ||
def delete_message(sender, receiver, msg_id): | ||
return f"DELETEed msg from {sender} to {receiver}" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
from . import Chat | ||
from chatroom.crypto import miller_rabin, genrandom, rsa | ||
|
||
from secrets import token_bytes | ||
from hashlib import sha3_256 | ||
from random import getrandbits | ||
|
||
PRIME_LEN = 15 | ||
ITERATIONS = 10 | ||
SALT_LEN = 16 | ||
|
||
|
||
class User: | ||
def __init__(self, user: str, pwd: str): | ||
# User login info | ||
self.user_id = getrandbits(64) | ||
self.username = user | ||
# TODO: hash + salt pwd | ||
#hash_obj = sha3_256() | ||
#hash_obj.update(token_bytes(SALT_LEN)) | ||
#hash_obj.update(bytes(pwd, encoding='UTF-8')) | ||
#self.password_hashsalt = hash_obj.digest() | ||
self.password = pwd | ||
# cryptographic key generation | ||
p = genrandom.gen_prime(PRIME_LEN, ITERATIONS) | ||
q = genrandom.gen_prime(PRIME_LEN, ITERATIONS) | ||
while (p == q) or (not miller_rabin.miller_rabin_test(q, ITERATIONS)): | ||
q += 2 | ||
(e, d) = rsa.rsa_gen_keypair(p, q) | ||
self.pub_key = (p * q, e) | ||
self.priv_key = d | ||
# Chats info | ||
self.chats = dict() | ||
def check_pwd(self, guess: str) -> bool: | ||
return self.password == guess | ||
|
||
def create_chat(recipient: str): | ||
"""Creates a new chat with the given recipient. | ||
""" | ||
newchat = Chat(recipient) | ||
self.chats[recipient] = newchat | ||
def __repr__(self): | ||
return 'User.Chatroom_user(' + self.username + ')' | ||
def __str__(self): | ||
s = 'User ' + self.user_id.__str__() + '\n' | ||
s += 'Username: ' + self.username + '\n' | ||
s += 'Password: ' + self.password + '\n' | ||
s += self.chats.__str__() + '\n' | ||
s += 'PUB_KEY:\n\t' + 'n = ' + hex(self.pub_key[0])[2:] + '\n\t' + 'e = ' + hex(self.pub_key[1])[2:] + '\n' | ||
s += 'PRIV_KEY: ' + hex(self.priv_key)[2:] + '\n' | ||
return s | ||
def __hash__(self) -> int: | ||
return self.user_id | ||
def __eq__(self, other) -> bool: | ||
return self.user_id == other.user_id |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import os | ||
|
||
from flask import Flask, render_template | ||
|
||
from . import (Auth, Chat, Msg) | ||
|
||
|
||
def create_app(testing=None): | ||
app = Flask(__name__, instance_relative_config=True) | ||
# app.config.from_mapping( | ||
# SECRET_KEY='dev') | ||
# if testing is None: | ||
# app.config.from_pyfile('config.py', silent=True) | ||
# else: | ||
# app.config.from_mapping(testing) | ||
app.register_blueprint(Auth.blueprint) | ||
app.register_blueprint(Chat.blueprint) | ||
app.register_blueprint(Msg.blueprint) | ||
|
||
print(app.url_map) | ||
return app | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
# a chatting client that uses RSA to encrypt messages |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
def cbc_mode(msg: bytes, iv: bytes, encrypt, pk: (int, int) , blocksize=1024): | ||
"""A generator that splits the message into blocks using CBC. | ||
This generator receives in input the message to be sent and splits it into | ||
fixed-lenght blocks (1K bits by default). Each block is derived from the previous | ||
using cipher block chaining (CBC). | ||
""" | ||
offset = 0 | ||
# An initialization vector (IV) is required to start the chain | ||
prev = int.from_bytes(iv, byteorder='big') | ||
while offset < len(msg): | ||
# Extracts the next block from the message | ||
block = msg[offset:offset+blocksize-1] | ||
print(f"block from {offset} to {offset+blocksize-1}") | ||
print(block) | ||
# Convert each block into an integer | ||
x = int.from_bytes(block, byteorder='big') | ||
print(f"x = {x}") | ||
# The plaintext is XOR'd with the previous block's ciphertext | ||
x = x ^ prev | ||
print(f"x ^ prev = {x}") | ||
# The resulting block is encrypted and sent to output | ||
cipher = encrypt(x, pk[0], pk[1]) | ||
print(f"cipher = {cipher}") | ||
yield cipher | ||
# Updates the cipher block and the offset inside the message | ||
prev = cipher | ||
offset += blocksize | ||
|
||
from . import genrandom | ||
from . import rsa | ||
|
||
if __name__ == "__main__": | ||
msg = input("msg: ") | ||
p = genrandom.gen_prime(384) | ||
q = genrandom.gen_prime(512) | ||
(e,n) = rsa.rsa_encrypt(p, q) | ||
# cipher in cbc mode | ||
gen = cbc_mode( | ||
bytes(msg, 'utf-8'), | ||
token_bytes(16), | ||
rsa.rsa_encrypt, | ||
(e,n), | ||
blocksize=16) | ||
for block in gen: | ||
print(f"=====\n{block}\n=====") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
def extended_euclid(a: int, b: int) -> (int, int, int): | ||
if b == 0: | ||
return (a, 1, 0) | ||
(rem, x1, y1) = extended_euclid(b, a % b) | ||
#print(f"rem = {rem}, x1 = {x1}, y1 = {y1}") | ||
return (rem, y1, x1 - (a // b) * y1) | ||
|
||
if __name__ == "__main__": | ||
a = int(input("a = ")) | ||
b = int(input("b = ")) | ||
print(f"Find x,y,z so that {a}x + {b}y = z") | ||
|
||
(z, x, y) = extended_euclid(a, b) | ||
print(f"z = {z}, x = {x}, y = {y}") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
def fastexp(x: int, y: int , m: int) -> int: | ||
"""Modular exponentiation function. | ||
This function implements the operation | ||
x^y mod m, where x, y and m are integers, | ||
doing a logarithmic number of operations | ||
""" | ||
next = x | ||
res = 1 | ||
while y > 0: | ||
if y % 2 == 1: | ||
res = (res * next) % m | ||
next = (next * next) % m; | ||
y = y // 2 | ||
return res | ||
|
||
if __name__ == "__main__": | ||
x = input("Enter x: ") | ||
y = input("Enter y: ") | ||
m = input("Enter m: ") | ||
res = fastexp(int(x), int(y), int(m)) | ||
print(f"{x}^{y} mod {m} = {res}") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
from secrets import randbits | ||
from . import miller_rabin | ||
|
||
def gen_prime(bitlen: int, iters: int) -> int: | ||
"""Generates a probably prime integer of bitlen bits. | ||
The Miller-Rabin primality test is performed on a randomly | ||
generated integer of (at least) bitlen bits. If such number | ||
passes iters iterations of the test then it's declared prime | ||
and returned. | ||
""" | ||
if bitlen <= 0 or iters <= 0: | ||
return -1 | ||
guess = randbits(bitlen) | ||
# ensure the highest bit set and odd number | ||
mask = 0x1 << (bitlen - 1) | ||
guess = guess|mask|0x1 | ||
while(not miller_rabin.miller_rabin_test(guess, iters)): | ||
guess += 2 | ||
return guess | ||
|
||
if __name__ == "__main__": | ||
bits = int(input("#bits = ")) | ||
iter = int(input("iterations = ")) | ||
print("probably prime:", gen_prime(bits, iter)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
from . import fastexp | ||
import secrets | ||
|
||
def miller_rabin_test(guess: int, iters: int) -> bool: | ||
"""Performs a Miller-Rabin primality test. | ||
The Miller-Rabin test on the primality of guess ensures that, | ||
if true is returned, then guess is prime with probability | ||
1 - 4^(-iters). If the function returs False, then guess in | ||
certaintly composite. | ||
""" | ||
w = 0 | ||
z = guess - 1 | ||
while(z % 2 == 0): | ||
w += 1 | ||
z = z // 2 | ||
i = 0; | ||
while i < iters: | ||
witness = 2 + secrets.randbelow(guess - 3) | ||
tmp = fastexp.fastexp(witness, z, guess) | ||
if not (tmp == 1 or tmp + 1 == guess): | ||
j = 1 | ||
while j < w: | ||
tmp = fastexp.fastexp(tmp, 2, guess) | ||
if tmp + 1 == guess: | ||
break | ||
j += 1 | ||
if j >= w: | ||
return False | ||
i += 1 | ||
return True | ||
|
||
if __name__ == "__main__": | ||
n = int(input("number: ")) | ||
iter = int(input("iterations: ")) | ||
if miller_rabin_test(n,iter): | ||
print(n, "is probably prime (probability >=", 1.0 - 4.0**(-iter)) | ||
else: | ||
print(n, "is certaintly composite") |
Oops, something went wrong.