HEX
Server: Apache/2.4.52 (Ubuntu)
System: Linux spn-python 5.15.0-89-generic #99-Ubuntu SMP Mon Oct 30 20:42:41 UTC 2023 x86_64
User: arjun (1000)
PHP: 8.1.2-1ubuntu2.20
Disabled: NONE
Upload Files
File: //home/arjun/projects/buyercall_forms/buyercall/buyercall/lib/util_crypto.py
import base64
import hashlib
import binascii
from Crypto import Random
from Crypto.Cipher import AES
from flask import current_app as app

from sqlalchemy import String
from sqlalchemy import TypeDecorator

BS = 16
pad = lambda s: s + (BS - len(s) % BS) * chr(BS - len(s) % BS)
unpad = lambda s: s[0:-s[-1]].decode()


class AESCipher:

    def __init__(self, key):
        self.key = key.encode('utf8')

    def encrypt(self, raw):
        raw = pad(raw)
        iv = Random.new().read(AES.block_size)
        cipher = AES.new(self.key, AES.MODE_CBC, iv)
        return base64.b64encode(iv + cipher.encrypt(raw.encode('utf8'))).decode()

    def decrypt(self, enc):
        enc = base64.b64decode(enc)
        iv = enc[:16]
        cipher = AES.new(self.key, AES.MODE_CBC, iv)
        return unpad(cipher.decrypt(enc[16:]))


# This class is being created to accommodate Symmetric Encryption Client Side where encryption is handled
# through a TypeDecorator for database field encryption. Read more;
# https://github.com/sqlalchemy/sqlalchemy/wiki/SymmetricEncryptionClientSide#example-two---use-typedecorator
class SymEncryption:

    def __init__(self, key, nonce):
        self.key = key.encode('utf8')
        self.nonce = nonce.encode('utf8')

    def sym_encrypt(self, data):
        cipher = AES.new(self.key, AES.MODE_EAX, nonce=self.nonce)
        data = data + (" " * (16 - (len(data) % 16)))
        return cipher.encrypt(data.encode("utf-8")).hex()

    def sym_decrypt(self, data):
        cipher = AES.new(self.key, AES.MODE_EAX, nonce=self.nonce)
        data = data.encode('utf-8')
        return cipher.decrypt(binascii.unhexlify(data)).decode("utf-8").rstrip()


class EncryptedValue(TypeDecorator):
    impl = String

    def process_bind_param(self, value, dialect):
        if type(value) == list:
            return value
        ec_key = app.config['SYM_CRYPTO_SECRET_KEY']
        ec_nonce = app.config['SYM_CRYPTO_NONCE']
        sym = SymEncryption(ec_key, ec_nonce)
        return sym.sym_encrypt(value)

    def process_result_value(self, value, dialect):
        if value:
            if len(value) < 32:
                return value
            else:
                try:
                    ec_key = app.config['SYM_CRYPTO_SECRET_KEY']
                    ec_nonce = app.config['SYM_CRYPTO_NONCE']
                    sym = SymEncryption(ec_key, ec_nonce)
                    return sym.sym_decrypt(value)
                except:
                    return value
        else:
            return ''

class SHA:
    @staticmethod
    def encrypt(hash_string):
        sha_signature = hashlib.sha256(hash_string.encode()).hexdigest()
        return sha_signature