Example #1
0
    def test_invalid_n(self, backend):
        # n is less than 2
        with pytest.raises(ValueError):
            Scrypt(b"NaCl", 64, 1, 8, 16, backend)

        # n is not a power of 2
        with pytest.raises(ValueError):
            Scrypt(b"NaCl", 64, 3, 8, 16, backend)
Example #2
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 #3
0
    def scrypt(self):

        cost = 14

        backend = default_backend()
        salt = os.urandom(16)

        start_time = time.time()

        while True:
            print('--- %s seconds ---' % (time.time() - start_time),
                  "cpu/memory cost factor", cost)
            if ((time.time() - start_time) < self.running_time):
                start_time = time.time()
                kdf = Scrypt(salt=salt,
                             length=32,
                             n=2**cost,
                             r=8,
                             p=1,
                             backend=backend)
                key = kdf.derive(str.encode(self.password))
            else:
                if ((time.time() - start_time) > self.threshold
                    ):  # Check if its way more than acceptable
                    print('--- %s seconds ---' % (time.time() - start_time),
                          "cpu/memory cost factor", cost - 1)
                else:
                    print('--- %s seconds ---' % (time.time() - start_time),
                          "cpu/memory cost factor", cost)
                break
            cost = cost + 1
Example #4
0
def get_key(verbose_pass=False):
    print("Please write your password")

    password1 = stdiomask.getpass()
    password1 = password1.encode()

    # Okey for this application, if this application is used for storring multiple users data or something like that
    # A non static salt should be used to avoid rainbow-table vulnerbilities
    salt = b'u\xcf(\n\xd5\x9c\x05\xffy\x97\x96\xb1@\x1f\rn'

    time1 = time.time()

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

    #key = base64.urlsafe_b64encode(kdf.derive(password1))
    key = kdf.derive(password1)

    print("It took ", time.time() - time1, " seconds to generate the key")

    print("Please verify your password")
    password2 = stdiomask.getpass()
    password2 = password2.encode()

    if password2 != password1:
        print("Passwords didn't match")
        exit(-1)

    return key
Example #5
0
def test_hand_shake_verify_password_return_true_if_given_password_is_correct_and_role_is_server(
):
    # Given
    password_to_verify = b"test_password"
    password_to_derive = b"test_password"
    password_salt = os.urandom(16)
    expected_result = True

    # derive
    kdf = Scrypt(
        salt=password_salt,
        length=32,
        n=2**14,
        r=8,
        p=1,
    )
    derived_password = kdf.derive(password_to_derive)
    authentication_information_server = {
        "password": {
            Handshake.PASSWORD_AUTH_METHOD_DERIVED_PASSWORD_KEY:
            derived_password,
            Handshake.PASSWORD_AUTH_METHOD_SALT_KEY: password_salt
        }
    }
    allowed_authentication_methods = ["password"]
    server = Handshake(
        role=Handshake.SERVER,
        authentication_information=authentication_information_server,
        allowed_authentication_methods=allowed_authentication_methods)
    # When
    result = server._verify_password(password_to_verify=password_to_verify)

    # Then
    assert result == expected_result
Example #6
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 #7
0
def derive(master_password: str, domain: str, user: str, counter: int,
           length: int, charset: str) -> str:
    if counter < 0 or counter > 255:
        raise ValueError(
            f'Counter {counter} cannot be represented by a single byte')
    master_password = ensure_bytes(master_password)
    domain = ensure_bytes(domain)
    user = ensure_bytes(user)

    salt = domain + b'\0' + user + b'\0' + bytes([counter])
    hash_bytes: bytes = Scrypt(salt=salt,
                               length=NUM_OCTATS,
                               n=N,
                               r=R,
                               p=P,
                               backend=BACKEND).derive(master_password)
    hash_int = bytes_to_big_endian_large_int(hash_bytes)
    result = [None] * length
    for i in range(length):
        if not hash_int:
            raise ValueError(
                f'Entropy exhausted. Requested derived password too long (len={length}).'
            )
        hash_int, residue = divmod(hash_int, len(charset))
        result[i] = charset[residue]
    return ''.join(result)
Example #8
0
def encrypt_file(plainpath, cipherpath, password):
    salt = os.urandom(16)
    kdf = Scrypt(salt=salt,
                 length=32,
                 n=2**14,
                 r=8,
                 p=1,
                 backend=default_backend())
    key = kdf.derive(password)

    iv = os.urandom(12)

    encryptor = Cipher(algorithms.AES(key),
                       modes.GCM(iv),
                       backend=default_backend()).encryptor()

    associated_data = iv + salt

    encryptor.authenticate_additional_data(associated_data)

    with open(cipherpath, "wb+") as fcipher:
        fcipher.write(b"\x00" * (12 + 16 + 16))

        with open(plainpath, "rb") as fplain:
            for plaintext in iter(lambda: fplain.read(READ_SIZE), b""):
                ciphertext = encryptor.update(plaintext)
                fcipher.write(ciphertext)
            ciphertext = encryptor.finalize()
            fcipher.write(ciphertext)

        header = associated_data + encryptor.tag
        fcipher.seek(0, 0)
        fcipher.write(header)
Example #9
0
 def kdf(cls, kdf, key, salt=None, dklen=None, verbose=False):
     assert (isinstance(key, bytes))
     if salt is None:
         salt = os.urandom(32)
     if dklen is None:
         dklen = kdf["dklen"]
     meta = {
         "name": kdf["name"],
         "salt": salt.hex(),
         "dklen": dklen,
     }
     t0 = time.time()
     if kdf["name"] == "scrypt":
         N = kdf.get("N", 1024 * 1024)
         r = kdf.get("r", 8)
         p = kdf.get("p", 1)
         meta.update({
             "N": N,
             "r": r,
             "p": p,
         })
         scrypt = Scrypt(salt=salt,
                         length=dklen,
                         n=N,
                         r=r,
                         p=p,
                         backend=_backend)
         dkey = scrypt.derive(key)
     else:
         raise NotImplementedError(kdf["name"])
     t1 = time.time()
     if verbose:
         print("Key derivation took %.3f sec" % (t1 - t0))
     return (meta, dkey)
Example #10
0
def hash_function(p, hashfunc="bcrypt", salt=None):
    """Generate hash from input string.

    Arguments:
        p {str, bytes} -- The input to be hashed.

    Keyword Arguments:
        hashfunc {str} -- Hashing algorithm to use. Options are "sha1" and "scrypt". (default: {"sha1"})

    Returns:
        bytes -- Hash of the input

    """
    if isinstance(p, str):  # Convert str to bytes if necessary
        p = p.encode()

    hashfunc = hashfunc.lower()  # Ensure the input will match the conditional case.

    if hashfunc == "sha1":
        return hashlib.sha1(p).hexdigest().encode()
    elif hashfunc == "scrypt":
        if not salt:
            salt = b"salt"
        instance = Scrypt(
            salt=b"salt", length=32, n=2 ** 14, r=8, p=1, backend=default_backend()
        )
        return instance.derive(p)
    elif hashfunc == "bcrypt":
        if not salt:
            salt = bcrypt.gensalt()
        return bcrypt.hashpw(p, salt)
    else:
        raise ValueError
def decrypt_file(cipherpath, plainpath, password):
    with open(cipherpath, "rb") as fcipher:
        # read the IV (12 bytes) and the salt (16 bytes)
        associated_data = fcipher.read(12+16)
        
        iv = associated_data[0:12]
        salt = associated_data[12:28]
        
        # derive the same key from the password + salt
        kdf = Scrypt(salt=salt, length=32,
                n=2**14, r=8, p=1,
                backend=default_backend())
        key = kdf.derive(password)
        
        # get the tag. GCM tags are always 16 bytes
        tag = fcipher.read(16)
        
        # Construct an AES-GCM Cipher object with the given key and IV
        # For decryption, the tag is passed in as a parameter
        decryptor = Cipher(
            algorithms.AES(key),
            modes.GCM(iv, tag),
            backend=default_backend()).decryptor()
        decryptor.authenticate_additional_data(associated_data)
        
        with open(plainpath, "wb+") as fplain:
            for ciphertext in iter(lambda: fcipher.read(READ_SIZE),b''):
                plaintext = decryptor.update(ciphertext)
                fplain.write(plaintext)
Example #12
0
    def _set_client_secret(self, client_secret):
        if self._salt:
            salt = b64decode(self._salt.encode('utf-8'))
        else:
            try:
                if not oauth2_settings('salt'):
                    raise ValueError(
                        'oauth2_provider.salt configuration required.'
                    )
                salt = b64decode(oauth2_settings('salt').encode('utf-8'))
            except AttributeError:
                return

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

        try:
            client_secret = bytes(client_secret, 'utf-8')
        except TypeError:
            pass
        self._client_secret = kdf.derive(client_secret)
Example #13
0
def query(ctxt):
    global r, passwords
    if REMOTE:
        menu(3)
        print("Query")
        print(r.recvline())
        r.sendline(ctxt)
        print(r.recvline())
        s = r.recvline()
        print("s:", s)
        if b"ERROR" in s:
            return 0
        print(r.recvline())
        r.recvline()
        return 1
    else:
        nonce, ciphertext = ctxt.split(b",")
        nonce = b64decode(nonce)
        ciphertext = b64decode(ciphertext)
        kdf = Scrypt(salt=b'',
                     length=16,
                     n=2**4,
                     r=8,
                     p=1,
                     backend=default_backend())
        key = kdf.derive(passwords[cur_idx])
        try:
            cipher = AESGCM(key)
            plaintext = cipher.decrypt(nonce, ciphertext, associated_data=None)
            return 1
        except:
            return 0
Example #14
0
def read(args, action):
    # read the file
    with contextlib.closing(FileDecryptor(args.archive,
                                          None)) as fd:  # no decryptor yet
        # parse the header
        header = HEADER.parse(fd.read_aad(HEADER.sizeof()))

        # setup encryption
        kdf_params = header['kdf_params']
        kdf = Scrypt(salt=kdf_params['salt'],
                     length=32,
                     n=kdf_params['n'],
                     r=kdf_params['r'],
                     p=kdf_params['p'],
                     backend=BACKEND)
        key = kdf.derive(get_password().encode('utf-8'))
        logging.debug(f'[read()] key={key.hex()}')
        cipher_params = header['cipher_params']
        cipher = Cipher(algorithms.ChaCha20(key, cipher_params['nonce']),
                        modes.Poly1305(),
                        backend=BACKEND)
        fd.init(cipher.decryptor())

        # read the tag
        fd.read_tag()

        # read the archive
        tar = tarfile.open(fileobj=fd, mode='r|*')
        action(tar)
Example #15
0
def test_verify_password_scrypt_return_true_if_given_password_is_correct_and_derived_with_scrypt(
):
    # Given
    password_to_verify = b"test_password"
    password_to_derive = b"test_password"
    password_salt = os.urandom(16)
    expected_result = True

    # derive
    kdf = Scrypt(
        salt=password_salt,
        length=32,
        n=2**14,
        r=8,
        p=1,
    )
    derived_password = kdf.derive(password_to_derive)

    # When
    result = verify_password_scrypt(password_to_verify=password_to_verify,
                                    derived_password=derived_password,
                                    password_salt=password_salt)

    # Then
    assert result == expected_result
Example #16
0
def aesDecrypt(iv, salt, password, payload):
    """ Decrypt AndSafe payload

    Keyword arguments:
    :param iv: IV for AES in CBC mode. In hexdecimal string format
    :param salt: salt for scrypt key derivation. In hexdecimal string format
    :param password: password for decryption. In string format
    :param payload: payload to decrypt. In hexdecimal string format
    :return: bytes of decrypted content
    """

    unpadder = padding.PKCS7(128).unpadder()
    backend = default_backend()
    kdf = Scrypt(salt=bytes.fromhex(salt),
                 length=32,
                 n=2**14,
                 r=8,
                 p=1,
                 backend=backend)

    key = kdf.derive(password.encode())
    cipher = Cipher(algorithms.AES(key),
                    modes.CBC(bytes.fromhex(iv)),
                    backend=backend)
    decryptor = cipher.decryptor()
    return unpadder.update(
        decryptor.update(bytes.fromhex(payload)) +
        decryptor.finalize()) + unpadder.finalize()
Example #17
0
def keyeststep10():
    received = ast.literal_eval(pkt1.smsg.actMsg)
    salt = received["salt"]
    aesgcm = AESGCM(temp_known_users[addr]["Sab"])
    try:
        u2_pubkey = int(
            aesgcm.decrypt(received["nonceforu2pubkey"],
                           received["enc_u2pubkey"], None))
        ssAB = pow(u2_pubkey, keyeststep8.u1_prikey, keyeststep8.s_p)

        backend = default_backend()
        # derive
        kdf = Scrypt(salt=salt, length=32, n=2**14, r=8, p=1, backend=backend)
        kAB = kdf.derive(bytes(ssAB))
        known_users[temp_known_users[addr]["name"]] = {
            "ssAB": kAB,
            "addr": addr
        }
        aesgcm = AESGCM(kAB)
        nonceformsg = os.urandom(12)
        message = aesgcm.encrypt(nonceformsg, keyestfunction.smsg, None)
        msgtosend = {"nonceformsg": nonceformsg, "msg": message}
        fillauthpacket(pkt1, "Data", 0, bytes(msgtosend))
        sendpacket(pkt1.SerializeToString(), addr[0], addr[1])
    except cryptography.exceptions.InvalidTag:
        print "Decrypt not okay"
Example #18
0
def decrypt_file(cipherpath, plainpath, password):
    with open(cipherpath, "rb") as fcipher:
        associated_data = fcipher.read(12 + 16)

        iv = associated_data[0:12]
        salt = associated_data[12:28]

        # Derive the same password with salt
        kdf = Scrypt(salt=salt,
                     length=32,
                     n=2**14,
                     r=8,
                     p=1,
                     backend=default_backend())

        key = kdf.derive(password)

        # GCM tags are always 16 bytes
        tag = fcipher.read(16)

        decryptor = Cipher(algorithms.AES(key),
                           modes.GCM(iv, tag),
                           backend=default_backend()).decryptor()

        decryptor.authenticate_additional_data(associated_data)

        with open(plainpath, "wb+") as fplain:
            for ciphertext in iter(lambda: fcipher.read(READ_SIZE), b""):
                plaintext = decryptor.update(ciphertext)
                fplain.write(plaintext)
Example #19
0
    def from_bytes(cls,
                   key_bytes: bytes,
                   password: Optional[bytes] = None,
                   _scrypt_cost: int = 20) -> 'UmbralKeyingMaterial':
        """
        Loads an UmbralKeyingMaterial from a urlsafe base64 encoded string.
        Optionally, if a password is provided it will decrypt the key using
        nacl's Salsa20-Poly1305 and Scrypt key derivation.

        WARNING: RFC7914 recommends that you use a 2^20 cost value for sensitive
        files. Unless you changed this when you called `to_bytes`, you should
        not change it here. It is NOT recommended to change the `_scrypt_cost`
        value unless you know what you're doing.
        """

        if password:
            salt = key_bytes[-16:]
            key_bytes = key_bytes[:-16]

            key = Scrypt(salt=salt,
                         length=SecretBox.KEY_SIZE,
                         n=2**_scrypt_cost,
                         r=8,
                         p=1,
                         backend=default_backend()).derive(password)

            key_bytes = SecretBox(key).decrypt(key_bytes)

        return cls(key_bytes)
Example #20
0
    def _derive_password(self, password):
        """
        Derives a password with a salt

        :param password: clear text password
        :type password: str
        :return: derived password and salt used encoded in base64
        :rtype: (str, str)
        """
        salt = urandom(SALT_SIZE)

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

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

        derived_password = kdf.derive(password)

        return b64encode(derived_password), b64encode(salt)
Example #21
0
def decrypt_key_with_password(key, password):
    """Turns a key and password into a scrypt key

    :param bytes key: The key bytes, containing the salt and encrypted key
    :param str password: The password in plaintext to derive the key from

    :returns: The decrypted key contained in ``key``
    :rtype: bytes
    """
    # get the salt and encrypted key
    salt, encryptedKey = key[0:SALT_SIZE], key[SALT_SIZE:]
    # re-create the file's key with the provided password and salt
    derivedKey = Scrypt(
        salt,
        backend=default_backend(),
        # key length for AES
        length=32,
        # The cost parameter
        n=32 * 1024,
        # same values as go-config-yourself
        r=8,
        p=1,
    ).derive(bytes(password, "utf-8"))
    # Return the decrypted key using the derived key
    return DataKeyService(derivedKey).decrypt(encryptedKey)
Example #22
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 #23
0
    def __fernetKey(self, salt, password):
        backend = default_backend()

        kdf = Scrypt(salt=salt, length=32, n=2**14, r=8, p=1, backend=backend)
        key = base64.urlsafe_b64encode(kdf.derive(b"%a" % password))

        return Fernet(key)
Example #24
0
    def to_bytes(self,
                 password: bytes = None,
                 _scrypt_cost: int = 20,
                 encoder: Callable = None):
        """
        Returns an Umbral private key as bytes optional symmetric encryption
        via nacl's Salsa20-Poly1305 and Scrypt key derivation. If a password
        is provided, the user must encode it to bytes.
        Optionally, allows an encoder to be passed in as a param to encode the
        data before returning it.

        WARNING: RFC7914 recommends that you use a 2^20 cost value for sensitive
        files. It is NOT recommended to change the `_scrypt_cost` value unless
        you know what you are doing.
        """
        umbral_privkey = self.bn_key.to_bytes()

        if password:
            salt = os.urandom(16)

            key = Scrypt(salt=salt,
                         length=SecretBox.KEY_SIZE,
                         n=2**_scrypt_cost,
                         r=8,
                         p=1,
                         backend=default_backend()).derive(password)

            umbral_privkey = SecretBox(key).encrypt(umbral_privkey)
            umbral_privkey += salt

        if encoder:
            umbral_privkey = encoder(umbral_privkey)

        return umbral_privkey
Example #25
0
def aesEncrypt(iv, salt, password, plain):
    """ Encrypt AndSafe plaintext

    Keyword arguments:
    :param iv: IV for AES in CBC mode. In hexdecimal string format
    :param salt: salt for scrypt key derivation. In hexdecimal string format
    :param password: password for encryption. In string format
    :param plain: plaintext to encrypt
    :return: bytes of encrypted content
    """

    padder = padding.PKCS7(128).padder()
    backend = default_backend()
    kdf = Scrypt(salt=bytes.fromhex(salt),
                 length=32,
                 n=2**14,
                 r=8,
                 p=1,
                 backend=backend)

    key = kdf.derive(password.encode())
    cipher = Cipher(algorithms.AES(key),
                    modes.CBC(bytes.fromhex(iv)),
                    backend=backend)
    encryptor = cipher.encryptor()
    return encryptor.update(
        padder.update(str.encode(plain)) +
        padder.finalize()) + encryptor.finalize()
Example #26
0
    def to_bytes(self, password: bytes=None, _scrypt_cost: int=20):
        """
        Returns an Umbral private key as a urlsafe base64 encoded string with
        optional symmetric encryption via nacl's Salsa20-Poly1305 and Scrypt
        key derivation. If a password is provided, the user must encode it to
        bytes.

        WARNING: RFC7914 recommends that you use a 2^20 cost value for sensitive
        files. It is NOT recommended to change the `_scrypt_cost` value unless
        you know what you are doing.
        """
        umbral_priv_key = self.bn_key.to_bytes()

        if password:
            salt = os.urandom(16)

            key = Scrypt(
                salt=salt,
                length=SecretBox.KEY_SIZE,
                n=2**_scrypt_cost,
                r=8,
                p=1,
                backend=default_backend()
            ).derive(password)

            umbral_priv_key = SecretBox(key).encrypt(umbral_priv_key)
            umbral_priv_key += salt

        encoded_key = base64.urlsafe_b64encode(umbral_priv_key)
        return encoded_key
Example #27
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 #28
0
def _derive_key_material_from_passphrase(salt: bytes,
                                         passphrase: str) -> bytes:
    """
    Uses Scrypt derivation to derive a key for encrypting key material.
    See RFC 7914 for n, r, and p value selections.
    This takes around ~5 seconds to perform.
    """
    try:
        key_material = Scrypt(salt=salt,
                              length=__WRAPPING_KEY_LENGTH,
                              n=2**20,
                              r=8,
                              p=1,
                              backend=default_backend()).derive(
                                  passphrase.encode())
    except InternalError as e:
        # OpenSSL Attempts to malloc 1 GB of mem for scrypt key derivation
        if e.err_code[0].reason == 65:
            raise MemoryError(
                "Key Derivation requires 1GB of memory: Please free up some memory and try again."
            )
        else:
            raise e
    else:
        return key_material
Example #29
0
    def from_bytes(cls, key_data: bytes, params: UmbralParameters=None,
                 password: bytes=None, _scrypt_cost: int=20):
        """
        Loads an Umbral private key from a urlsafe base64 encoded string.
        Optionally, if a password is provided it will decrypt the key using
        nacl's Salsa20-Poly1305 and Scrypt key derivation.

        WARNING: RFC7914 recommends that you use a 2^20 cost value for sensitive
        files. Unless you changed this when you called `to_bytes`, you should
        not change it here. It is NOT recommended to change the `_scrypt_cost`
        value unless you know what you're doing.
        """
        if params is None:
            params = default_params()

        key_bytes = base64.urlsafe_b64decode(key_data)

        if password:
            salt = key_bytes[-16:]
            key_bytes = key_bytes[:-16]

            key = Scrypt(
                salt=salt,
                length=SecretBox.KEY_SIZE,
                n=2**_scrypt_cost,
                r=8,
                p=1,
                backend=default_backend()
            ).derive(password)

            key_bytes = SecretBox(key).decrypt(key_bytes)

        bn_key = BigNum.from_bytes(key_bytes, params.curve)
        return cls(bn_key, params)
Example #30
0
def authlaststep(d, addr, aupkt1):
    # print d
    # print "cc:", d["clientcontri"]
    # print "secret:", d["secret"]
    # print "sc:", d["sumcontri"]
    session_key = pow(
        pow(long(d["clientcontri"]), long(d["b"]), p) *
        pow(long(d["secret"]), (d["b"] * d["u"]), p), 1, p)
    # print "sk:", session_key

    batch = ast.literal_eval(aupkt1.smsg.actMsg)
    # print "batch", batch

    ct = batch["Enc"]
    # print "ct", ct
    C3 = batch["C3"]
    # print 'c3', C3
    nonce = batch["nonce"]
    # print "nonce", nonce
    salt = batch["salt"]
    # print "salt", salt

    c2 = d["C2"]

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

    key = kdf.derive(bytes(session_key))
    # print "key", key

    aesgcm = AESGCM(key)
    try:
        ct = long(aesgcm.decrypt(nonce, ct, None))
        if c2 == ct:
            # print "values match"
            nonce2 = os.urandom(12)
            encc3 = aesgcm.encrypt(nonce2, bytes(C3), None)
            # print "enc okay"
            retd = {"encc3": encc3, "nonce2": nonce2}
            fillauthpacket(aupkt1, "Login", 6, bytes(retd))
            # print "pf"
            sendpacket(aupkt1.SerializeToString(), addr[0], addr[1])
            # print "6 sent"
            connected_users[addr] = {
                "uname": temp_values[addr]["uname"],
                "ipaddr": addr[0],
                "port": addr[1],
                "skey": key
            }
            currusers[temp_values[addr]["uname"]] = {
                "ipaddr": addr[0],
                "port": addr[1]
            }
            del temp_values[addr]
    except cryptography.exceptions.InvalidTag:
        print "Someone entered an incorrect password"
        fillauthpacket(aupkt1, "Login", 6, "Incorrect")
        sendpacket(aupkt1.SerializeToString(), addr[0], addr[1])