from bcrypt import gensalt, hashpw, checkpw
from ecies import encrypt, decrypt
from config import PRIVKEYHEX, PUBKEYHEX, CLOUDFRONT_KEY_BASE64, APP_MODE, FRONTEND_TO_SERVER_PRV_KEY_BASE64, SERVER_TO_FRONTEND_PUB_KEY_BASE64, SERVER_TO_FRONTEND_PRV_KEY_BASE64
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import padding
import os
import base64
from codecs import decode
"""
Method :Generate Password hash
@Param :
1.password : type -> str
Return : Hashed password
"""
def generate_password_hash(password: str) -> str:
passwd = bytes(password, 'latin-1')
salt = gensalt()
hashed = hashpw(passwd, salt)
return hashed.decode('latin-1')
"""
Method :check user input password with hashedPassword stored in database
@Param :
1.password : type -> str
2. hashedPassword : type -> str
Return : True or False
"""
def check_password_hash(password: str, hasedPassword: str) -> bool:
if checkpw(password.encode('latin-1'), hasedPassword.encode('latin-1')):
return True
else:
return False
"""
Method :Encrypt data , if None don't encrypt
@Param :
1.plaintext : type -> str
Return : Encrypted hex data
"""
def encrypt_data(plaintext: str) -> bytes:
if plaintext is None:
return plaintext
encrypted = encrypt(PUBKEYHEX, plaintext.encode())
return encrypted.hex()
"""
Method :Decrypted data , if None return Null
@Param :
1.encrypted: type -> str
Return : Decrypted data
"""
def decrypt_data(encrypted) -> bytes:
if encrypted is None:
return None
decrypted = decrypt(PRIVKEYHEX, bytes.fromhex(encrypted))
return decrypted.decode()
"""
Method :Decrypted front end data , if None return Null
@Param :
1.encrypted: type -> str
Return : Decrypted data
"""
def decrypt_frontend_data_to_server(encrypted):
if encrypted is None:
return None
else:
java_out = encrypted.encode('UTF-8')
ciphertext = decode(java_out, 'base64')
private_key_string = base64.b64decode(FRONTEND_TO_SERVER_PRV_KEY_BASE64)
private_key_ascii = private_key_string.decode('ascii')
private_key = serialization.load_pem_private_key(
private_key_ascii.encode('UTF-8'),
password=None,
backend=default_backend()
)
#Decrypt the front end data
decrypted = private_key.decrypt(
ciphertext,
padding.OAEP(
mgf=padding.MGF1(algorithm=hashes.SHA256()),
algorithm=hashes.SHA256(),
label=None
)
)
return decrypted.decode()
"""
Method :Encrypt server to frontend data , if None return Null
@Param :
1.text: type -> str
Return : Encrypted data
"""
def encrypt_server_data_to_frontend(plaintext: str):
if plaintext is None:
return None
# if APP_MODE == "dev":
# return plaintext
else:
plaintext = plaintext.encode('UTF-8')
public_key_string = base64.b64decode(SERVER_TO_FRONTEND_PUB_KEY_BASE64)
public_key_ascii = public_key_string.decode('ascii')
#Pem file kept in config
pub_key = serialization.load_pem_public_key(
public_key_ascii.encode('UTF-8'),
backend=default_backend()
)
#Encrypt the server data
encrypted = pub_key.encrypt(
plaintext,
padding.OAEP(
mgf=padding.MGF1(algorithm=hashes.SHA256()),
algorithm=hashes.SHA256(),
label=None
)
)
return base64.b64encode(encrypted).decode("utf-8")
"""
Method :Decrypted server end data (use at endpoint) , if None return Null
@Param :
1.encrypted: type -> str
Return : Decrypted data
"""
def decrypt_server_data_to_frontend(encrypted):
if encrypted is None:
return None
else:
endpoint_out = encrypted.encode('UTF-8')
ciphertext = decode(endpoint_out, 'base64')
private_key_string = base64.b64decode(SERVER_TO_FRONTEND_PRV_KEY_BASE64)
private_key_ascii = private_key_string.decode('ascii')
private_key = serialization.load_pem_private_key(
private_key_ascii.encode('UTF-8'),
password=None,
backend=default_backend()
)
#Decrypt the front end data
decrypted = private_key.decrypt(
ciphertext,
padding.OAEP(
mgf=padding.MGF1(algorithm=hashes.SHA256()),
algorithm=hashes.SHA256(),
label=None
)
)
return decrypted.decode()
"""
Method :Check cloudfront key file
@Param :
1.message
Return : Private Key signer
"""
def rsa_signer(message):
#Using env pem file
private_key_string = base64.b64decode(CLOUDFRONT_KEY_BASE64)
private_key_ascii = private_key_string.decode('ascii')
private_key = serialization.load_pem_private_key(
private_key_ascii.encode('UTF-8'),
password=None,
backend=default_backend()
)
return private_key.sign(message, padding.PKCS1v15(), hashes.SHA1())