Example #1
0
    def _verify_password(self, password, derived_password, salt):
        """

        :param password: clear text received from the user that wants to be authenticated
        :param password: str
        :return: true if password received matches the one stored
        :rtype: bool
        """
        derived_password = b64decode(derived_password)
        salt = b64decode(salt)

        password = bytes(password, "utf-8")

        kdf = Scrypt(
            salt    = salt,
            length  = 32,
            n       = 2**14,
            r       = 8,
            p       = 1,
            backend = default_backend()
        )

        try:
            kdf.verify(password, derived_password)
            return True
        except InvalidKey:
            return False
Example #2
0
def api_token():
    user = request.form["user"]
    password = request.form["password"].encode("utf8")
    conn = sqlite3.connect("user.db")
    c = conn.cursor()
    result = c.execute(
        "SELECT salt, pass, admin from users where user=?", [user]
    ).fetchone()
    conn.close()
    if result is None:
        abort(403)

    salt, spass, admin = result
    kdf = Scrypt(
        salt=salt, length=32, n=2**14, r=8, p=1, backend=default_backend()
    )
    try:
        kdf.verify(password, spass)
    except InvalidKey:
        print("invalid password")
        abort(403)

    payload = json.dumps({"admin": admin, "user": user}, sort_keys=True)
    # encrypt the payload
    return _encrypt(payload)
Example #3
0
def verify_password_scrypt(password_to_verify: bytes, derived_password: bytes,
                           password_salt: bytes):
    """Check if the input password correspond to the instance derived password and salt.

    :param password_to_verify: The password to verify as bytes.
    :param derived_password: The derived password used to verify the given password as bytes.
    :param password_salt: The salt used to derive the password as bytes.

    :return: True if is verified, else False.
    """
    password_correct = False
    kdf = Scrypt(
        salt=password_salt,
        length=32,
        n=2**14,
        r=8,
        p=1,
    )
    try:
        kdf.verify(password_to_verify, derived_password)
        password_correct = True
    except InvalidKey:
        pass
    except AlreadyFinalized:
        pass
    return password_correct
Example #4
0
 def verify_hash(self, password):
     backend = default_backend()
     kdf = Scrypt(salt=self.salt,
                  length=32,
                  n=2**14,
                  r=8,
                  p=1,
                  backend=backend)
     kdf.verify(password, self.password_hash)
Example #5
0
    def enterFolderPwd(self, folder_path):
        #user has to enter folder password
        #compared to stored hash
        #repeated until the correct password was entered
        while True:
            folder_pwd = input(
                "This is your first access to this folder. Please enter the folder password: "******"salt"],
                         length=32,
                         n=2**4,
                         r=8,
                         p=1,
                         backend=default_backend())
            try:
                kdf.verify(folder_pwd.encode(), self.pwd_db[folder_path])
            except InvalidKey:
                print("The password is wrong.")
                continue
            else:
                break

        print("Folder password will be stored for access in the future.")

        #get correct user password to encrypt the folder password for this user
        while True:
            pwd = input("Please enter the user password: "******"salt"],
                         length=32,
                         n=2**4,
                         r=8,
                         p=1,
                         backend=default_backend())
            try:
                kdf.verify(pwd.encode(), self.users[self.currentUser]["pwd"])
            except InvalidKey:
                print("The password is wrong.")
                continue
            else:
                break

        #encrypt the folder password using the user password and store it
        kdf = PBKDF2HMAC(algorithm=hashes.SHA256(),
                         length=32,
                         salt=self.users[self.currentUser]["salt"],
                         iterations=100000,
                         backend=default_backend())
        pwd_key = kdf.derive(pwd.encode())
        f = Fernet(urlsafe_b64encode(pwd_key))
        encrypted_folder_pwd = f.encrypt(folder_pwd.encode())
        self.users[self.currentUser]["folders"].update(
            {folder_path: encrypted_folder_pwd})
Example #6
0
    def test_invalid_verify(self, backend):
        password = b"password"
        work_factor = 1024
        block_size = 8
        parallelization_factor = 16
        length = 64
        salt = b"NaCl"
        derived_key = b"fdbabe1c9d3472007856e7190d01e9fe7c6ad7cbc8237830e773"

        scrypt = Scrypt(salt, length, work_factor, block_size, parallelization_factor, backend)

        with pytest.raises(InvalidKey):
            scrypt.verify(password, binascii.unhexlify(derived_key))
class Login():
    """Class that creates a simple password protection to th dahsboard"""

    def __init__(self, pw_hashed, salt, callback, *cback_args, **cback_kwargs):
        """
        pw_hashed:  binary string
            This is the string that must be entered to access the dahsboard.
        salt:       binary string
            The salt used for the hashing process of the password
        callback:   function
            Function to call if the user enters the right password.
        cback_args: any
            the arguments for your callback function (e.g. "my_title")
        cback_kwargs:   any
            the named arguments for your callback function (e.g. name='Bob')
        """

        self.password = pw_hashed
        self.callback = callback
        self.cback_args = cback_args
        self.cback_kwargs = cback_kwargs
        self._backend = default_backend()
        self.salt = salt

        self.password_text = bk.models.Div(
            text="Enter the password then press OK")
        self.password_field = bk.models.widgets.inputs.PasswordInput()
        self.wrong_password_text = bk.models.Div(
            text="Wrong password. Try again.")

        self.confirm_button = bk.models.Button(label="OK",
            button_type="primary")
        self.confirm_button.on_click(self.verify_password)
        self.col = pn.Column(self.password_text, self.password_field,
            self.confirm_button)
        # If i did not use Panel, it would be like this:
        # self.col = bk.models.Column(self.password_text,
        #   self.password_field, self.confirm_button)

    def verify_password(self, *e):
        self.kdf = Scrypt(salt=self.salt, length=32,
            n=2**14, r=8, p=1, backend=self._backend)
        try:
            self.kdf.verify(str(self.password_field.value).encode(),
                           self.password)
            self.password_text.text = "Success"
            self.callback(*self.cback_args, **self.cback_kwargs)
        except InvalidKey:
            if self.wrong_password_text not in self.col:
                self.col.append(self.wrong_password_text)
Example #8
0
    def test_invalid_verify(self, backend):
        password = b"password"
        work_factor = 1024
        block_size = 8
        parallelization_factor = 16
        length = 64
        salt = b"NaCl"
        derived_key = b"fdbabe1c9d3472007856e7190d01e9fe7c6ad7cbc8237830e773"

        scrypt = Scrypt(salt, length, work_factor, block_size,
                        parallelization_factor, backend)

        with pytest.raises(InvalidKey):
            scrypt.verify(password, binascii.unhexlify(derived_key))
Example #9
0
def verify_scrypt_key(salt, passphrase, key_bytes):

    passphrase_bytes = bytes(passphrase, 'utf8')
    salt_bytes = bytes(salt, 'utf8')

    # Verify key
    kdf = Scrypt(salt=salt_bytes,
                 length=32,
                 n=2**18,
                 p=1,
                 r=8,
                 backend=default_backend())
    try:
        kdf.verify(passphrase_bytes, key_bytes)
    except InvalidKey:
        return False
    else:
        return True
Example #10
0
async def check_credentials(email: str, password: str, domain: str) -> bool:
    key_material = password.encode("utf-8")
    try:
        user = await User.objects.filter(active=True,
                                         email=email,
                                         domain=domain).get()
        expected_key = b64decode(user.password)
    except NoMatch:
        debug(f"No active user '{email}' from domain '{domain}' found")
        key_material = b"Password that 100% not matching, I swear"
        expected_key = b"Password that 100% not matching, trust me"

    kdf = Scrypt(conf.SALT, length=32, n=2**16, r=8, p=1)
    try:
        kdf.verify(key_material, expected_key)
        return True
    except InvalidKey:
        return False
Example #11
0
def verificate_hash_token(access_token: Dict[str, str],
                          jti_token: str) -> bool:
    resp = False
    backend = default_backend()
    token_hashed = Scrypt(salt=binascii.unhexlify(access_token['salt']),
                          length=NUMBER_OF_BYTES,
                          n=SCRYPT_N,
                          r=SCRYPT_R,
                          p=SCRYPT_P,
                          backend=backend)
    try:
        token_hashed.verify(binascii.unhexlify(jti_token),
                            binascii.unhexlify(access_token['jti']))
        resp = True
    except InvalidKey:
        rollbar.report_message('Error: Access token does not match', 'error')

    return resp
Example #12
0
    def test_verify(self, backend, params):
        _skip_if_memory_limited(_MEM_LIMIT, params)
        password = params["password"]
        work_factor = int(params["n"])
        block_size = int(params["r"])
        parallelization_factor = int(params["p"])
        length = int(params["length"])
        salt = params["salt"]
        derived_key = params["derived_key"]

        scrypt = Scrypt(
            salt,
            length,
            work_factor,
            block_size,
            parallelization_factor,
            backend,
        )
        scrypt.verify(password, binascii.unhexlify(derived_key))
Example #13
0
def get_passphrase():
    if os.path.exists(PASSPHRASE_FILEPATH):
        prompt = 'Passphrase: '
    else:
        prompt = 'Define passphrase: '

    passphrase = getpass(prompt=prompt).encode()

    if os.path.exists(PASSPHRASE_FILEPATH):
        with open(SALT_FILEPATH, 'rb') as file:
            salt = file.read()

        with open(PASSPHRASE_FILEPATH, 'rb') as file:
            passphrase_key = file.read()

        kdf = Scrypt(salt=salt,
                     length=32,
                     n=2**14,
                     r=8,
                     p=1,
                     backend=default_backend())

        kdf.verify(passphrase, passphrase_key)

    else:
        salt = os.urandom(16)
        with open(SALT_FILEPATH, 'wb') as file:
            file.write(salt)

        kdf = Scrypt(salt=salt,
                     length=32,
                     n=2**14,
                     r=8,
                     p=1,
                     backend=default_backend())

        passphrase_key = kdf.derive(passphrase)

        with open(PASSPHRASE_FILEPATH, 'wb') as file:
            file.write(passphrase_key)

    return passphrase
Example #14
0
def scrypt_key(password, mcf='', bits=512):
    """
        RFC 7914 recommends values of r=8 and p=1 while scaling n as appropriate for your system.
        The scrypt paper suggests a minimum value of n=2**14 for interactive logins (t < 100ms),
        or n=2**20 for more sensitive files (t < 5s).
    """
    if isinstance(password, unicode):
        password = password.encode('utf-8')
    if not mcf:
        salt = os.urandom(16)  # NIST SP 800-132 recommends 128-bits or longer
        cost = 2**14
        kdf = Scrypt(salt=salt,
                     length=bits / 8,
                     n=cost,
                     r=8,
                     p=1,
                     backend=default_backend())
        key = kdf.derive(password)
    # Verify key, or derive with specific iterations and/or salt
    elif mcf[0] == '$':
        fields = mcf.split('$')
        if len(fields) > 4 and fields[1] == 'scrypt':
            if not fields[2]:
                cost = 2**14
            else:
                cost = int(fields[2])
            if not fields[3]:
                salt = os.urandom(16)
            else:
                salt = base64.b64decode(fields[3])
            kdf = Scrypt(salt=salt,
                         length=bits / 8,
                         n=cost,
                         r=8,
                         p=1,
                         backend=default_backend())
            try:
                kdf.verify(password, base64.b64decode(fields[4]))
            except InvalidKey:
                return ''
    return '$scrypt$' + str(cost) + '$' + base64.b64encode(
        salt) + '$' + base64.b64encode(key)
Example #15
0
    def test_verify(self, backend, params):
        password = params["password"]
        work_factor = int(params["n"])
        block_size = int(params["r"])
        parallelization_factor = int(params["p"])
        length = int(params["length"])
        salt = params["salt"]
        derived_key = params["derived_key"]

        scrypt = Scrypt(salt, length, work_factor, block_size, parallelization_factor, backend)
        assert scrypt.verify(password, binascii.unhexlify(derived_key)) is None
Example #16
0
    def test_verify(self, backend, params):
        password = params["password"]
        work_factor = int(params["n"])
        block_size = int(params["r"])
        parallelization_factor = int(params["p"])
        length = int(params["length"])
        salt = params["salt"]
        derived_key = params["derived_key"]

        scrypt = Scrypt(salt, length, work_factor, block_size,
                        parallelization_factor, backend)
        assert scrypt.verify(password, binascii.unhexlify(derived_key)) is None
Example #17
0
def crack_scrypt(key, salt):

    try:
        salt = unhexlify(sys.argv[1].encode())
        key = unhexlify(sys.argv[2].encode())
    except binascii.Error:
        print('Non-hexadecimal data on salt and/or key', file=sys.stderr)
        return False

    backend = default_backend()

    for number in range(10000):

        kdf = Scrypt(salt=salt, length=32, n=2**14, r=8, p=1, backend=backend)

        try:
            kdf.verify(str(number).encode(), key)
            print('Cracked! Password:', number)
            break
        except InvalidKey:
            pass
Example #18
0
def verify_secret_key(password):
    try:
        with open(SYM_KEY_PATH, "rb") as file:
            salt_and_key = file.read()
    except FileNotFoundError:
        return False, "No secret key found"

    salt = salt_and_key[:SALT_SIZE]
    key = salt_and_key[SALT_SIZE:]
    length = len(key)

    kdf = Scrypt(salt=salt,
                 length=length,
                 n=SCRYPT_COST_PARAMETER,
                 r=SCRYPT_BLOCK_SIZE_PARAMETER,
                 p=SCRYPT_PARALLELIZATION_PARAMETER)
    try:
        kdf.verify(bytes(password, encoding='utf-8'), key)
    except InvalidKey:
        return False, "Invalid key", None
    except AlreadyFinalized:
        return False, "Error was encountered during the verification process", None

    return True, "Password successfully verified", key
Example #19
0
  def secretGenerator(self) :

        password = self.readPassword()

        backend = default_backend()

        # Salts should be randomly generated
        salt = os.urandom(16)

        kdf = Scrypt(
            salt=salt,
            length=32,
            n=2**14,
            r=8,
            p=1,
            backend=backend
        )


        key = kdf.derive(password)


        # verify
        kdf = Scrypt(
            salt=salt,
            length=32,
            n=2**14,
            r=8,
            p=1,
            backend=backend
        )

        kdf.verify(password, key)

        # return the passphrase
        return key
Example #20
0
def login(username, password, **kwargs):

    conn = sqlite3.connect('db_users.sqlite')
    conn.set_trace_callback(print)
    conn.row_factory = sqlite3.Row
    c = conn.cursor()

    user = c.execute("SELECT * FROM users WHERE username = ?",
                     (username, )).fetchone()

    if not user:
        #print('The user doesnt exists')
        return False

    backend = default_backend()

    kdf = Scrypt(salt=unhexlify(user['salt']),
                 length=32,
                 n=2**14,
                 r=8,
                 p=1,
                 backend=backend)

    try:
        kdf.verify(password.encode(), unhexlify(user['password']))
        #print('valid')
        return username
    except InvalidKey:
        #print('invalid1')
        return False
    except Exception as e:
        #print('invalid2', e)
        return False

    #print('No deberia haber llegado aca')
    return False
Example #21
0
#import os
import base64
from cryptography.hazmat.primitives.kdf.scrypt import Scrypt
from cryptography.hazmat.backends import default_backend

backend = default_backend()
#Salt should be generated randomly
salt = open("salt.txt", "rb").read()
#print(salt)
#derive
kdf = Scrypt(salt=salt, length=32, n=2**14, r=8, p=1, backend=backend)

key = kdf.derive(b"the pass word")

newkey = base64.urlsafe_b64encode(key)

with open("derivedKey.key", "wb") as deKey:
    deKey.write(newkey)

#print(key)
#verify
kdf = Scrypt(salt=salt, length=32, n=2**14, r=8, p=1, backend=backend)

kdf.verify(b"the pass word", key)
Example #22
0
import sys
import os
import binascii
from binascii import unhexlify

from cryptography.hazmat.primitives.kdf.scrypt import Scrypt
from cryptography.hazmat.backends import default_backend
from cryptography.exceptions import InvalidKey

password = sys.argv[1].encode()

try:
    salt = unhexlify(sys.argv[2].encode())
    key = unhexlify(sys.argv[3].encode())
except binascii.Error:
    print('Non-hexadecimal data on salt and/or key', file=sys.stderr)
    sys.exit(1)

backend = default_backend()

#print(hexlify(key).decode())

# verify
kdf = Scrypt(salt=salt, length=32, n=2**14, r=8, p=1, backend=backend)

try:
    kdf.verify(password, key)
    print('Valid')
except InvalidKey:
    print('Invalid')
Example #23
0
from cryptography.hazmat.primitives.kdf.scrypt import Scrypt
from cryptography.hazmat.backends import default_backend
import os
key = b'\x95\xda\nr\x0b\xed\xe8:4Q\xb7\x9f\xf8\xe0\x953\xadBvUN\x17KC\xbd\xdb\x93?:\x91O\x9f'
salt = b'\x1dkC;\xda\x11^\xa4zMb\xcfr`\r\x1b'
kdf = Scrypt(salt=salt,
             length=32,
             r=8,
             p=1,
             n=2**14,
             backend=default_backend())
kdf.verify(b'motherfucking password', key)
print("Success! (Exception if mismatch)")
Example #24
0
import base64
import os
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.kdf.scrypt import Scrypt
from cryptography.hazmat.backends import default_backend

salt = os.urandom(16)

kdf = Scrypt(salt=salt,
             length=32,
             n=2**14,
             r=8,
             p=1,
             backend=default_backend())

#scrytp Derive key
key = kdf.derive(b"my password")
print base64.b64encode(key)

# ANSI X9.63  verify Function

kdf = Scrypt(salt=salt,
             length=32,
             n=2**14,
             r=8,
             p=1,
             backend=default_backend())

kdf.verify(b"my password", key)
Example #25
0
import os
from cryptography.hazmat.primitives.kdf.scrypt import Scrypt
from cryptography.hazmat.backends import default_backend

salt = os.urandom(16)

kdf = Scrypt(salt=salt, length=32,
                n=2**14, r=8, p=1,
                backend=default_backend())

key = kdf.derive(b"my great password")
print("KDF output:", key.hex())

kdf = Scrypt(salt=salt, length=32,
             n=2**14, r=8, p=1,
             backend=default_backend())
kdf.verify(b"my great password", key)
print("Success! (Exception if mismatch)")

# If we got here, we passed
print("[PASS]")
Example #26
0
import os
from cryptography.hazmat.primitives.kdf.scrypt import Scrypt
from cryptography.hazmat.backends import default_backend

# Generate random salt
salt = os.urandom(16)

scrypt_config = {
    "salt": salt,
    "length": 32,
    "n": 2**14,
    "r": 8,
    "p": 1,
    "backend": default_backend(),
}

kdf = Scrypt(**scrypt_config)
key = kdf.derive(b"my great password")

# Scrypt instances can only be used once
kdf2 = Scrypt(**scrypt_config)
try:
    kdf2.verify(b"blblblbl", key)
except:
    print("Wrong password")

kdf3 = Scrypt(**scrypt_config)
kdf3.verify(b"my great password", key)
print("success!")
Example #27
0
    def addDek(self, file_name, dek, tag, iv):
        #get folder path by eliminating filename from file path contained in <file_name>
        folder_path = "/".join(file_name.split("/")[0:-1])
        name = file_name.split("/")[-1]
        print(name)

        #user has to input user password until the hash of it is equal to the stored user password hash (until the password is correct)
        while True:
            pwd = input("user  password: "******"salt"],
                         length=32,
                         n=2**4,
                         r=8,
                         p=1,
                         backend=default_backend())
            try:
                kdf.verify(pwd.encode(), self.users[self.currentUser]["pwd"])
            except InvalidKey:
                print("The password is wrong.")
                continue
            else:
                break

        #get encrypted folder password and encrypted kek
        encrypted_folder_pwd = self.users[
            self.currentUser]["folders"][folder_path]
        stored_kek = self.getEncryptionFolderKek(folder_path)

        #decrypt folder password using the user password
        kdf = PBKDF2HMAC(algorithm=hashes.SHA256(),
                         length=32,
                         salt=self.users[self.currentUser]["salt"],
                         iterations=100000,
                         backend=default_backend())
        pwd_key = kdf.derive(pwd.encode())

        f = Fernet(urlsafe_b64encode(pwd_key))
        folder_pwd = f.decrypt(encrypted_folder_pwd)

        #decrypt the kek using the decrypted folder password
        kdf = PBKDF2HMAC(algorithm=hashes.SHA256(),
                         length=32,
                         salt=self.kek_db[folder_path]["salt"],
                         iterations=100000,
                         backend=default_backend())
        folder_key = kdf.derive(folder_pwd)
        f = Fernet(urlsafe_b64encode(folder_key))
        folder_kek = f.decrypt(stored_kek)

        if self.kek_db[folder_path]["rotate"]:
            print(
                "Key rotation happened. Reencrypting all DEKs of files in this directory with the new KEK."
            )

            new_kek = Fernet.generate_key()
            new_f = Fernet(new_kek)
            f = Fernet(folder_kek)

            for currentFile in os.listdir(path_secure + folder_path):
                if currentFile == name:
                    continue
                file_encrypted_dek = self.dek_db[folder_path + "/" +
                                                 currentFile]['dek']
                file_dek = f.decrypt(file_encrypted_dek)
                new_file_encrypted_dek = new_f.encrypt(file_dek)
                self.dek_db[folder_path + "/" + currentFile].update(
                    {"dek": new_file_encrypted_dek})

            f = Fernet(urlsafe_b64encode(folder_key))
            new_encrypted_kek = f.encrypt(new_kek)
            self.kek_db[folder_path].update({
                "decryption_kek": new_encrypted_kek,
                "encryption_kek": new_encrypted_kek
            })
            self.kek_db[folder_path].update({"rotate": False})
            folder_kek = new_kek

        #encrypt dek using the decrypted folder kek
        f = Fernet(folder_kek)
        dek = f.encrypt(dek)

        #store encrypted data encrytion key, authentication tag and initialization vector in dek database
        self.dek_db[file_name].update({'dek': dek, 'tag': tag, 'iv': iv})
Example #28
0
    def getDek(self, file_name):
        #get folder path by eliminating the file name of file path
        folder_path = "/".join(file_name.split("/")[0:-1])

        #get user password
        #compare entered password to stored hash of correct user password
        #repeated until they are equal
        while True:
            pwd = input("Enter your user password")
            kdf = Scrypt(salt=self.users[self.currentUser]["salt"],
                         length=32,
                         n=2**4,
                         r=8,
                         p=1,
                         backend=default_backend())
            try:
                kdf.verify(pwd.encode(), self.users[self.currentUser]["pwd"])
            except InvalidKey:
                print("The password is wrong.")
                continue
            else:
                break

        #get encrypted folder password and folder kek
        encrypted_folder_pwd = self.users[
            self.currentUser]["folders"][folder_path]
        encrypted_kek = self.getDecryptionFolderKek(folder_path)

        #decrypt folder password
        kdf = PBKDF2HMAC(algorithm=hashes.SHA256(),
                         length=32,
                         salt=self.users[self.currentUser]["salt"],
                         iterations=100000,
                         backend=default_backend())
        pwd_key = kdf.derive(pwd.encode())
        f = Fernet(urlsafe_b64encode(pwd_key))
        folder_pwd = f.decrypt(encrypted_folder_pwd)

        #decrypt kek
        kdf = PBKDF2HMAC(algorithm=hashes.SHA256(),
                         length=32,
                         salt=self.kek_db[folder_path]["salt"],
                         iterations=100000,
                         backend=default_backend())
        folder_key = kdf.derive(folder_pwd)
        f = Fernet(urlsafe_b64encode(folder_key))
        kek = f.decrypt(encrypted_kek)

        #decrypt dek
        f = Fernet(kek)
        dek = f.decrypt(self.dek_db[file_name]['dek'])

        if self.kek_db[folder_path]["rotate"]:
            print(
                "Key rotation happened. Reencrypting all DEKs of files in this directory with the new KEK."
            )

            new_kek = Fernet.generate_key()
            new_f = Fernet(new_kek)

            for currentFile in os.listdir(path_secure + folder_path):
                file_encrypted_dek = self.dek_db[folder_path + "/" +
                                                 currentFile]['dek']
                file_dek = f.decrypt(file_encrypted_dek)
                new_file_encrypted_dek = new_f.encrypt(file_dek)
                self.dek_db[folder_path + "/" + currentFile].update(
                    {"dek": new_file_encrypted_dek})

            f = Fernet(urlsafe_b64encode(folder_key))
            new_encrypted_kek = f.encrypt(new_kek)
            self.kek_db[folder_path].update({
                "decryption_kek": new_encrypted_kek,
                "encryption_kek": new_encrypted_kek
            })
            self.kek_db[folder_path].update({"rotate": False})

        return dek
Example #29
0
def oauth2_token(request):
    """
    * In the case of an incoming authentication request a POST is made
    with the following structure.

        POST /token HTTP/1.1
        Host: server.example.com
        Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
        Content-Type: application/x-www-form-urlencoded

        grant_type=password&username=johndoe&password=A3ddj3w

    The basic auth header contains the client_id:client_secret base64
    encoded for client authentication.

    The username and password are form encoded as part of the body. This
    request *must* be made over https.

    The response to this request will be, assuming no error:

        HTTP/1.1 200 OK
        Content-Type: application/json;charset=UTF-8
        Cache-Control: no-store
        Pragma: no-cache

        {
          "access_token":"2YotnFZFEjr1zCsicMWpAA",
          "token_type":"bearer",
          "expires_in":3600,
          "refresh_token":"tGzv3JOkF0XG5Qx2TlKW",
          "user_id":1234,
        }

    * In the case of a token refresh request a POST with the following
    structure is required:

        POST /token HTTP/1.1
        Host: server.example.com
        Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
        Content-Type: application/x-www-form-urlencoded

        grant_type=refresh_token&refresh_token=tGzv3JOkF0XG5Qx2TlKW&user_id=1234

    The response will be the same as above with a new access_token and
    refresh_token.
    """

    # Make sure this is a POST.
    if request.method != 'POST':
        log.info('rejected request due to invalid method: %s' % request.method)
        return HTTPMethodNotAllowed(
            'This endpoint only supports the POST method.')

    getClientCredentials(request)

    # Make sure we got a client_id and secret through the authorization
    # policy. Note that you should only get here if not using the Oauth2
    # authorization policy or access was granted through the AuthTKt policy.
    if (not hasattr(request, 'client_id') or
        not hasattr(request, 'client_secret')):
        log.info('did not receive client credentials')
        return HTTPUnauthorized('Invalid client credentials')

    client = db.query(Oauth2Client).filter_by(
        client_id=request.client_id).first()

    # Again, the authorization policy should catch this, but check again.
    if not oauth2_settings('salt'):
        raise ValueError('oauth2_provider.salt configuration required.')
    salt = b64decode(oauth2_settings('salt').encode('utf-8'))
    kdf = Scrypt(
        salt=salt,
        length=64,
        n=2 ** 14,
        r=8,
        p=1,
        backend=backend
    )

    try:
        client_secret = request.client_secret
        try:
            client_secret = bytes(client_secret, 'utf-8')
        except TypeError:
            client_secret = client_secret.encode('utf-8')
        kdf.verify(client_secret, client.client_secret)
        bad_secret = False
    except (AttributeError, InvalidKey):
        bad_secret = True
    if not client or bad_secret:
        log.info('received invalid client credentials')
        return HTTPBadRequest(InvalidRequest(
            error_description='Invalid client credentials'))

    # Check for supported grant type. This is a required field of the form
    # submission.
    resp = None
    grant_type = request.POST.get('grant_type')
    if grant_type == 'password':
        resp = handle_password(request, client)
    elif grant_type == 'refresh_token':
        resp = handle_refresh_token(request, client)
    else:
        log.info('invalid grant type: %s' % grant_type)
        return HTTPBadRequest(UnsupportedGrantType(error_description='Only '
            'password and refresh_token grant types are supported by this '
            'authentication server'))

    add_cache_headers(request)
    return resp
Example #30
0
    def addFolderKek(self, folder_path):
        #set folder password which allows user to gain access to shared_folder
        folder_pwd = input("Set folder password used for first access: ")

        #store hash of folder password to verify that entered password is the correct one later (needed on first access to folder)
        salt = os.urandom(16)
        kdf = Scrypt(salt=salt,
                     length=32,
                     n=2**4,
                     r=8,
                     p=1,
                     backend=default_backend())
        key = kdf.derive(folder_pwd.encode())
        self.pwd_db.update({folder_path: key})

        #generate kek of folder
        generated_kek = Fernet.generate_key()

        #encrypt the kek using the folder password and store the encrypted kek
        kdf = PBKDF2HMAC(algorithm=hashes.SHA256(),
                         length=32,
                         salt=salt,
                         iterations=100000,
                         backend=default_backend())
        folder_key = kdf.derive(folder_pwd.encode())
        f = Fernet(urlsafe_b64encode(folder_key))
        folder_kek = f.encrypt(generated_kek)
        self.kek_db.update({
            folder_path: {
                "decryption_kek": folder_kek,
                "encryption_kek": folder_kek,
                "salt": salt,
                "rotate": False
            }
        })

        while True:
            user_pwd = input("Enter your user password: "******"salt"],
                         length=32,
                         n=2**4,
                         r=8,
                         p=1,
                         backend=default_backend())
            try:
                kdf.verify(user_pwd.encode(),
                           self.users[self.currentUser]["pwd"])
            except InvalidKey:
                print("The password is wrong.")
                continue
            else:
                break

        #store folder password which was encrypted using user password
        kdf = PBKDF2HMAC(algorithm=hashes.SHA256(),
                         length=32,
                         salt=self.users[self.currentUser]["salt"],
                         iterations=100000,
                         backend=default_backend())
        user_key = kdf.derive(user_pwd.encode())
        f = Fernet(urlsafe_b64encode(user_key))
        encrypted_folder_pwd = f.encrypt(folder_pwd.encode())
        self.users[self.currentUser]["folders"].update(
            {folder_path: encrypted_folder_pwd})