Example #1
0
    def scramble_salt(self,
                      password,
                      salt,
                      server_key,
                      client_key,
                      rounds=None):
        """Scrambles a given salt using the specified server key.
        """
        msg = salt + server_key + client_key

        hmac_digest = self.salt_key(password, salt, rounds)

        hash = Hash(self.ALGORITHM(), self.backend)
        hash.update(hmac_digest)
        hash_digest = hash.finalize()

        key_hash = Hash(self.ALGORITHM(), self.backend)
        key_hash.update(hash_digest)
        key_hash_digest = key_hash.finalize()

        sig = HMAC(key_hash_digest, self.ALGORITHM(), self.backend)
        sig.update(msg)
        sig_digest = sig.finalize()

        return self.xor(sig_digest, hash_digest)
Example #2
0
def double_sha256(bytestr):
    hash1 = Hash(SHA256, DEFAULT_BACKEND)
    hash1.update(bytestr)
    hash1 = hash1.finalize()

    hash2 = Hash(SHA256, DEFAULT_BACKEND)
    hash2.update(hash1)
    hash2 = hash2.finalize()

    return hash2
Example #3
0
def decrypt(secret, hash, data, file=False):
    """
    Decrypt per telegram docs at https://core.telegram.org/passport.

    Args:
        secret (:obj:`str` or :obj:`bytes`): The encryption secret, either as bytes or as a
            base64 encoded string.
        hash (:obj:`str` or :obj:`bytes`): The hash, either as bytes or as a
            base64 encoded string.
        data (:obj:`str` or :obj:`bytes`): The data to decrypt, either as bytes or as a
            base64 encoded string.
        file (:obj:`bool`): Force data to be treated as raw data, instead of trying to
            b64decode it.

    Raises:
        :class:`TelegramDecryptionError`: Given hash does not match hash of decrypted data.

    Returns:
        :obj:`bytes`: The decrypted data as bytes.

    """
    # First make sure that if secret, hash, or data was base64 encoded, to decode it into bytes
    try:
        secret = b64decode(secret)
    except (binascii.Error, TypeError):
        pass
    try:
        hash = b64decode(hash)
    except (binascii.Error, TypeError):
        pass
    if not file:
        try:
            data = b64decode(data)
        except (binascii.Error, TypeError):
            pass
    # Make a SHA512 hash of secret + update
    digest = Hash(SHA512(), backend=default_backend())
    digest.update(secret + hash)
    secret_hash_hash = digest.finalize()
    # First 32 chars is our key, next 16 is the initialisation vector
    key, iv = secret_hash_hash[:32], secret_hash_hash[32:32 + 16]
    # Init a AES-CBC cipher and decrypt the data
    cipher = Cipher(AES(key), CBC(iv), backend=default_backend())
    decryptor = cipher.decryptor()
    data = decryptor.update(data) + decryptor.finalize()
    # Calculate SHA256 hash of the decrypted data
    digest = Hash(SHA256(), backend=default_backend())
    digest.update(data)
    data_hash = digest.finalize()
    # If the newly calculated hash did not match the one telegram gave us
    if data_hash != hash:
        # Raise a error that is caught inside telegram.PassportData and transformed into a warning
        raise TelegramDecryptionError("Hashes are not equal! {} != {}".format(data_hash, hash))
    # Return data without padding
    return data[bord(data[0]):]
Example #4
0
 def derive(self, key_material):
     if not isinstance(key_material, bytes):
         raise TypeError("key_material must be bytes.")
     h = Hash(self._algorithm(), backend=self._backend)
     h.update(key_material)
     h.update(self._salt)
     derived_key = h.finalize()
     for i in xrange(self._iterations - 1):
         h = Hash(self._algorithm(), backend=self._backend)
         h.update(derived_key)
         derived_key = h.finalize()
     return derived_key
Example #5
0
 def check_pcrs(self, pcrs, qinfo, halg):
     if not qinfo.pcrSelect.count == 1:
         raise Exception('too many PCR selections')
     parray = TPMS_PCR_SELECTION_ARRAY.frompointer(
         qinfo.pcrSelect.pcrSelections)
     pcrsel = parray[0]
     if not pcrsel.hash == TPM2_ALG_SHA256:  # FIXME
         raise Exception('PCR bank does not match')
     h = Hash(halg(), default_backend())
     sel = 0
     for ps, v in pcrs.items():
         # FIXME, check keys
         p = int(ps)
         sel = sel | (1 << p)
         pv = b16decode(v)
         h.update(pv)
     dig = h.finalize()
     selb = sel.to_bytes(pcrsel.sizeofSelect, 'big')
     qselb = bytearray()
     qsarray = BYTE_ARRAY.frompointer(pcrsel.pcrSelect)
     for i in range(0, pcrsel.sizeofSelect):
         qselb.append(qsarray[i])
     qselb = bytes(qselb)
     if not qselb == selb:
         raise Exception('PCR selection does not match')
     qdig = buffer_to_bytes(qinfo.pcrDigest)
     if not dig == qdig:
         raise Exception('PCR digest does not match')
def setup_cipher_rc4(salt, password, encrypt=False):
    hash = Hash(SHA1(), default_backend())
    hash.update(salt + bytes(password, 'ascii'))
    cipher = Cipher(algorithms.ARC4(hash.finalize()), None, default_backend())
    cryptor = cipher.encryptor() if encrypt else cipher.decryptor()
    cryptor.update(bytes(RC4_SKIP))
    return cryptor
    def validate_access_token(access_token, access_scope=scopes['client']):
        try:
            token = tokenserializer.loads(access_token)
            client_id = token.get('client', None)
            if not client_id:
                raise BadSignature('Token does not contain a client ID.')

            client = User.query.filter(User.id == client_id).first()
            if not client:
                raise BadSignature('No such client.')

            h = Hash(SHA256(), default_backend())
            h.update(access_token.encode('utf-8'))

            if not client.token == h.finalize():
                abort(401, message='Invalid access token.')

            if token.get('scope') > access_scope:
                abort(403, message='Insufficient Privileges.')

        except SignatureExpired:
            abort(401, message='Expired access token.')
        except BadSignature:
            abort(401, message='Bad access token.')
        except:
            raise
Example #8
0
 def _get_ciphertext_digest(ciphertext):
     if type(ciphertext) is str:
         ciphertext = bytes(ciphertext, 'utf-8')
     hash_provider = Hash(SHA512(), default_backend())
     hash_provider.update(ciphertext)
     return base64.b64encode(
         hash_provider.finalize()).decode('utf-8').rstrip("=")
Example #9
0
def decrypt_ec(data, ec_private_key):
    ephemeral_public_key = load_ec_public_key(data[:65])
    shared_secret = ec_private_key.exchange(ec.ECDH(), ephemeral_public_key)
    digest = Hash(SHA256(), backend=_CRYPTO_BACKEND)
    digest.update(shared_secret)
    encryption_key = digest.finalize()
    return decrypt_aes_v2(data[65:], encryption_key)
Example #10
0
    def _rebuild_index(self):
        index = {}
        cipher = CipherContext(self._password)

        for path in self._secrets.glob('*.secret'):
            with open(path, 'rb') as file:
                contents = file.read()

            plaintext = decompress(cipher.decrypt(contents))

            # We extract the path out of the plaintext first.
            path_size = unpack('>H', plaintext[:2])[0]
            short_path = plaintext[2:path_size + 2].decode()

            # This is the true plaintext.
            plaintext = plaintext[path_size + 2:]

            # We need to generate a hash for the file.
            hasher = Hash(BLAKE2b(64))
            hasher.update(plaintext)

            index[short_path] = {
                'path': short_path,
                'uuid': path.stem,
                'checksum': hasher.finalize().hex()
            }

        return index
def onion_name(key):
    pub_bytes = key.public_key().public_bytes(
        encoding=serialization.Encoding.DER,
        format=serialization.PublicFormat.PKCS1)
    hash = Hash(SHA1(), backend=default_backend())
    hash.update(pub_bytes)
    return b32encode(hash.finalize()[:10]).lower().decode('ascii') + '.onion'
Example #12
0
    def decrypt_encryption_key_fallback(self):
        """Decrypts the encryption key using the FALLBACK method. In this method, the
        context string, usually "CredEncryption" or "PSEEncryption", is encrypted using
        a derivation of a fixed key hardcoded in CommonCryptoLib, and used as key to
        encrypt the actual encryption key used in the file with the AES cipher.

        :return: Encryption key decrypted
        :rtype: string
        """
        log_lps.debug("Obtaining encryption key with FALLBACK LPS mode")

        digest = Hash(SHA1(), backend=default_backend())
        digest.update(cred_key_lps_fallback)
        hashed_key = digest.finalize()

        hmac = HMAC(hashed_key, SHA1(), backend=default_backend())
        hmac.update(self.context)
        default_key = hmac.finalize()[:16]

        iv = "\x00" * 16
        decryptor = Cipher(algorithms.AES(default_key),
                           modes.CBC(iv),
                           backend=default_backend()).decryptor()
        encryption_key = decryptor.update(
            self.encrypted_key) + decryptor.finalize()

        return encryption_key
Example #13
0
 def hash(self, data):
     digest = Hash(MD5(), backend=openssl_backend)
     to_hash = "data={}||lpv={}||{}".format(
         data.decode('ascii'), '.'.join(map(str, self.version)), self.key)
     digest.update(to_hash.encode('utf8'))
     intermediate = digest.finalize().hex()
     return intermediate[8:24]
Example #14
0
 def encrypt_request(self, serialized_request):
     padder = self.session_key_padding.padder()
     serialized_request_padded = padder.update(serialized_request) + padder.finalize()
     encryptor = self.session_key_cipher.encryptor()
     serialized_request_ciphertext = encryptor.update(serialized_request_padded) + encryptor.finalize()
     hasher = Hash(self.digest_algorithm)
     hasher.update(serialized_request)
     serialized_request_digest = hasher.finalize()
     session_key_ciphertext = self.c2_public_key.encrypt(
         self.session_key,
         OAEP(MGF1(self.digest_algorithm), self.digest_algorithm, None),
     )
     session_key_ciphertext_size = self.c2_public_key.key_size // 8
     serialized_request_digest_size = self.digest_algorithm.digest_size
     serialized_request_ciphertext_size = len(serialized_request_ciphertext)
     encrypted_request = struct.pack(
         '<%ds%ds%ds' % (
             session_key_ciphertext_size,
             serialized_request_digest_size,
             serialized_request_ciphertext_size
         ),
         session_key_ciphertext,
         serialized_request_digest,
         serialized_request_ciphertext,
     )
     return encrypted_request
def decrypt(secret, hash, data):
    """
    Decrypt per telegram docs at https://core.telegram.org/passport.

    Args:
        secret (:obj:`str` or :obj:`bytes`): The encryption secret, either as bytes or as a
            base64 encoded string.
        hash (:obj:`str` or :obj:`bytes`): The hash, either as bytes or as a
            base64 encoded string.
        data (:obj:`str` or :obj:`bytes`): The data to decrypt, either as bytes or as a
            base64 encoded string.
        file (:obj:`bool`): Force data to be treated as raw data, instead of trying to
            b64decode it.

    Raises:
        :class:`PassportDecryptionError`: Given hash does not match hash of decrypted data.

    Returns:
        :obj:`bytes`: The decrypted data as bytes.

    """
    if not CRYPTO_INSTALLED:
        raise RuntimeError(
            "To use Telegram Passports, PTB must be installed via `pip install "
            "python-telegram-bot[passport]`."
        )
    # Make a SHA512 hash of secret + update
    digest = Hash(SHA512(), backend=default_backend())
    digest.update(secret + hash)
    secret_hash_hash = digest.finalize()
    # First 32 chars is our key, next 16 is the initialisation vector
    key, init_vector = secret_hash_hash[:32], secret_hash_hash[32 : 32 + 16]
    # Init a AES-CBC cipher and decrypt the data
    cipher = Cipher(AES(key), CBC(init_vector), backend=default_backend())
    decryptor = cipher.decryptor()
    data = decryptor.update(data) + decryptor.finalize()
    # Calculate SHA256 hash of the decrypted data
    digest = Hash(SHA256(), backend=default_backend())
    digest.update(data)
    data_hash = digest.finalize()
    # If the newly calculated hash did not match the one telegram gave us
    if data_hash != hash:
        # Raise a error that is caught inside telegram.PassportData and transformed into a warning
        raise PassportDecryptionError(f"Hashes are not equal! {data_hash} != {hash}")
    # Return data without padding
    return data[data[0] :]
Example #16
0
def encrypt_ec(data, ec_public_key):
    e_private_key, e_public_key = generate_ec_key()
    shared_secret = e_private_key.exchange(ec.ECDH(), ec_public_key)
    digest = Hash(SHA256(), backend=_CRYPTO_BACKEND)
    digest.update(shared_secret)
    encryption_key = digest.finalize()
    return unload_ec_public_key(e_public_key) + encrypt_aes_v2(
        data, encryption_key)
def setup_cipher_aes(salt, password, encrypt=False):
    hash = Hash(SHA256(), default_backend())
    hash.update(salt + bytes(password, 'ascii'))
    cipher = Cipher(algorithms.AES(hash.finalize()[:16]), modes.CTR(salt[:16]),
                    default_backend())
    cryptor = cipher.encryptor() if encrypt else cipher.decryptor()
    cryptor.update(bytes(AES_SKIP))
    return cryptor
    def __init__(self, mail, password, scope=scopes['client']):
        self.email = mail
        self.scope = scope

        h = Hash(SHA256(), default_backend())
        h.update(password.encode('utf-8'))

        self.password = h.finalize()
Example #19
0
def hash_password(password: str, salt: str) -> str:
    """ Generates the password hash for the given user

    :param password: The password to hash
    :param salt: The salt(base64) to use in hash
    :return: The password hash
    """
    hash_ = Hash(SHA3_512())
    hash_.update(password.encode('ascii') + b64decode(salt.encode('ascii')))
    digest = hash_.finalize()
    hash_ = Hash(SHA3_512())
    hash_.update(digest)
    digest = hash_.finalize()
    hash_ = Hash(SHA3_512())
    hash_.update(digest + b64decode(salt.encode('ascii')))
    digest = hash_.finalize()
    return b64encode(digest).decode('ascii')
Example #20
0
 def get_public_key_digest(self):
     pem_public_key = self.get_pem_public_key()
     pem_public_key = [x for x in pem_public_key if len(x) > 0]
     pem_public_key.pop(0)
     pem_public_key.pop(-1)
     key_string = ''.join(pem_public_key)
     hash_provider = Hash(SHA512(), default_backend())
     hash_provider.update(bytes(key_string, 'utf-8'))
     return binascii.hexlify(hash_provider.finalize())
Example #21
0
def get_name(area):
    halg = tpm2_to_crypto_alg(area.nameAlg)
    algp = area.nameAlg.to_bytes(2, 'big')
    pbuf = marshal(area)
    h = Hash(halg(), default_backend())
    h.update(pbuf)
    dig = h.finalize()
    name = algp + dig
    return name
Example #22
0
def opdata1_decrypt_master_key(data, key, hmac_key, aes_size=C_AES_SIZE, ignore_hmac=False):
    key_size = KEY_SIZE[aes_size]
    bare_key = opdata1_decrypt_item(data, key, hmac_key, aes_size=aes_size, ignore_hmac=ignore_hmac)
    # XXX: got the following step from jeff@agilebits (as opposed to the
    # docs anywhere)
    digest = Hash(SHA512(), backend=_backend)
    digest.update(bare_key)
    hashed_key = digest.finalize()
    return hashed_key[:key_size], hashed_key[key_size:]
Example #23
0
    def compute_hash(cls, data: bytes) -> bytes:
        h = Hash(algorithm=cls.get_hash_func(), backend=default_backend())
        h.update(data)
        digest = h.finalize()

        if cls.trunc_size:
            digest = digest[:cls.trunc_size]

        return digest
Example #24
0
    def sha512(self, plaintext):
        """ Perform SHA-512 hash """

        digest = Hash(SHA512(), backend=default_backend())
        digest.update(bytes(plaintext.encode('UTF-8')))
        hash = digest.finalize()

        #return binascii.hexlify(bytearray(hash))
        return base64.b16encode(hash).decode()
Example #25
0
 def __init__(self, data_secret: bytes, data_hash: bytes) -> None:
     digest = Hash(SHA512())
     digest.update(data_secret)
     digest.update(data_hash)
     secret_hash = digest.finalize()
     key = secret_hash[:self._key_size]
     iv = secret_hash[self._key_size:self._key_size + self._iv_size]
     self._data_hash: Final[bytes] = data_hash
     self._cipher: Final[Cipher] = Cipher(AES(key), CBC(iv))
Example #26
0
def sha256(message):
    """Generates a SHA256 hash of a message"""
    if isinstance(message, str):
        message = bytes(message, encoding='utf-8')
    elif isinstance(message, bytearray):
        message = bytes(message)
    digest = Hash(SHA256(), backend=default_backend())
    digest.update(message)
    return digest.finalize()
Example #27
0
 def decrypt(self, ciphertext: bytes) -> bytes:
     decryptor = self._cipher.decryptor()  # type: ignore
     assert isinstance(decryptor, CipherContext)
     plaintext = decryptor.update(ciphertext) + decryptor.finalize()
     digest = Hash(SHA256())
     digest.update(plaintext)
     computed_hash = digest.finalize()
     if not bytes_eq(computed_hash, self._data_hash):
         raise RuntimeError('Decryption error')
     return plaintext[plaintext[0]:]
Example #28
0
def _shorten_hmac_key(key: bytes) -> bytes:
    if len(key) > SHA1_BLOCK_SIZE:
        h = Hash(SHA1(), default_backend())  # nosec
        h.update(key)
        key = h.finalize()
    elif len(key) > HMAC_KEY_SIZE:
        raise NotSupportedError(
            "Key lengths > {} bytes not supported".format(HMAC_KEY_SIZE)
        )
    return key
Example #29
0
    def _build_index(self):
        index = {}

        for path in get_git_files(self._repository):
            if (self._repository / path).is_file():
                uuid = str(uuid4())

                while index.get(uuid):
                    uuid = str(uuid4())

                hasher = Hash(BLAKE2b(64))

                with open(self._repository / path, 'rb') as file:
                    hasher.update(file.read())

                index[str(path)] = {
                    'path': str(path),
                    'uuid': uuid,
                    'checksum': hasher.finalize().hex()
                }

        for path in (self._repository / '.git').glob('**/*'):
            if path.is_file():
                uuid = str(uuid4())

                while index.get(uuid):
                    uuid = str(uuid4())

                hasher = Hash(BLAKE2b(64))

                with open(path, 'rb') as file:
                    hasher.update(file.read())

                short_path = path.relative_to(self._repository)

                index[str(short_path)] = {
                    'path': str(short_path),
                    'uuid': uuid,
                    'checksum': hasher.finalize().hex()
                }

        return index
    def login(email, password):

        user = User.query.filter(User.email == email).first()

        h = Hash(SHA256(), default_backend())
        h.update(password.encode('utf-8'))

        if not user.password == h.finalize():
            return None
        else:
            return user