コード例 #1
0
ファイル: test_fernet.py プロジェクト: festoni/AES_CTR_CMAC
    def test_integer_bytes_conversion2(self):
        # test integer to bytes, then bytes to integer == original
        key = Fernet.generate_key()
        fernet = Fernet(key)

        for i in range(10000):
            assert fernet._bytes_to_integer(fernet._integer_to_bytes(i)) == i
コード例 #2
0
ファイル: projectconfig.py プロジェクト: Miguel-J/pineboo
    def load_projectxml(self) -> bool:
        """Collect the connection information from an xml file."""

        file_name = self.filename
        if not os.path.isfile(file_name):
            raise ValueError("El proyecto %r no existe." % file_name)

        tree = ET.parse(file_name)
        root = tree.getroot()
        version = VersionNumber(root.get("Version"), default="1.0")
        self.version = version
        self.description = ""
        for xmldescription in root.findall("name"):
            self.description = xmldescription.text or ""
        profile_pwd = ""
        for profile in root.findall("profile-data"):
            profile_pwd = getattr(profile.find("password"), "text", "")
            if profile_pwd:
                break

        self.password_required = True
        self.checkProfilePasswordForVersion(self.project_password, profile_pwd,
                                            version)

        if self.project_password and self.version > VERSION_1_1:
            key_salt = hashlib.sha256(profile_pwd.encode()).digest()
            key = hashlib.pbkdf2_hmac("sha256", self.project_password.encode(),
                                      key_salt, 10000)
            key64 = base64.urlsafe_b64encode(key)
            self.fernet = Fernet(key64)
        else:
            self.fernet = None

        from pineboolib.application.database.pnsqldrivers import PNSqlDrivers

        sql_drivers_manager = PNSqlDrivers()
        self.database = self.retrieveCipherSubElement(root, "database-name")
        for db in root.findall("database-server"):
            self.host = self.retrieveCipherSubElement(db, "host")
            port_text = self.retrieveCipherSubElement(db, "port")
            self.port = int(port_text) if port_text else None
            self.type = self.retrieveCipherSubElement(db, "type")

            # FIXME: Move this to project, or to the connection handler.
            if self.type not in sql_drivers_manager.aliasList():
                LOGGER.warning(
                    "Esta versión de pineboo no soporta el driver '%s'" %
                    self.type)

        for credentials in root.findall("database-credentials"):
            self.username = self.retrieveCipherSubElement(
                credentials, "username")
            self.password = self.retrieveCipherSubElement(
                credentials, "password")
            if self.password and self.fernet is None:
                self.password = base64.b64decode(self.password).decode()
        self.password_required = False

        return True
コード例 #3
0
ファイル: test_fernet.py プロジェクト: festoni/AES_CTR_CMAC
    def test_subkey_gen_bad_length(self):
        # test subkey generation function when given bad input length
        key = Fernet.generate_key()
        fernet = Fernet(key)

        KEY = os.urandom(15)
        with pytest.raises(AssertionError) as e:
            fernet._generate_subkey(KEY)
コード例 #4
0
    def test_Functionality(self):
        key = Fernet.generate_key()
        fernet = Fernet(key)

        # decrypt(encrypt(msg)) == msg
        for i in xrange(20):
            msg = os.urandom(6)
            assert fernet.decrypt(fernet.encrypt(msg)) == msg
コード例 #5
0
ファイル: test_fernet.py プロジェクト: festoni/AES_CTR_CMAC
    def test_integer_bytes_conversion(self):
        # test bytes to integer, then integer to bytes == original
        key = Fernet.generate_key()
        fernet = Fernet(key)

        for i in range(10000):
            b = os.urandom(16)
            assert fernet._integer_to_bytes(fernet._bytes_to_integer(b)) == b
コード例 #6
0
ファイル: test_fernet.py プロジェクト: festoni/AES_CTR_CMAC
    def test_empty_bytes(self):
        # test _bytes_to_integer function when given empty bytes
        key = Fernet.generate_key()
        fernet = Fernet(key)

        b = os.urandom(0)
        with pytest.raises(AssertionError) as e:
            fernet._bytes_to_integer(b)
コード例 #7
0
ファイル: test_fernet.py プロジェクト: festoni/AES_CTR_CMAC
    def test_xor(self):
        # check xor for normal functionality
        key = Fernet.generate_key()
        fernet = Fernet(key)

        x = bytes(bytearray(16))
        for i in xrange(20):
            y = os.urandom(16)
            assert(fernet._xor(x, y) == y) # xor of 0 and y == y
コード例 #8
0
def encrypt(filename, filename_encrpt, keys):
    f = Fernet(keys)
    with open(filename, "rb") as file:
        # read all file data
        file_data = file.read()
    # encrypt data
    encrypted_data = f.encrypt(file_data)
    # write the encrypted file
    with open(filename_encrpt, "wb") as file:
        file.write(encrypted_data)
コード例 #9
0
ファイル: test_fernet.py プロジェクト: festoni/AES_CTR_CMAC
    def test_AES_ECB(self):
        # AES_ECB_128 test with RFC test vectors
        key = Fernet.generate_key()
        fernet = Fernet(key)

        KEY = '2b7e151628aed2a6abf7158809cf4f3c'.decode('hex')
        AES_128 = '7df76b0c1ab899b33e42f047b91b546f'.decode('hex')
        CONST_ZERO = 0x00000000000000000000000000000000

        assert fernet._AES_ECB(fernet._integer_to_bytes(CONST_ZERO), KEY) == AES_128
コード例 #10
0
ファイル: test_fernet.py プロジェクト: festoni/AES_CTR_CMAC
    def test_Functionality_extensive(self):
        # extensively test the decrpytion(encryption(msg)) == msg
        key = Fernet.generate_key()
        fernet = Fernet(key)

        # decrypt(encrypt(msg)) == msg
        for i in xrange(100):
            for l in range(20):
                msg = os.urandom(l)
                assert fernet.decrypt(fernet.encrypt(msg)) == msg
コード例 #11
0
ファイル: test_fernet.py プロジェクト: festoni/AES_CTR_CMAC
    def test_CTR_test_vectors(self):
        # test CTR encryption and decryption using official RFC test vectors
        key = Fernet.generate_key()
        fernet = Fernet(key)

        KEY = 'AE6852F8121067CC4BF7A5765577F39E'.decode('hex')
        IV = '00000030000000000000000000000001'.decode('hex')
        PLAINTEXT = '53696E676C6520626C6F636B206D7367'.decode('hex')
        CIPHERTEXT = 'E4095D4FB7A7B3792D6175A3261311B8'.decode('hex')

        assert fernet._AES_CTR_encrypt(PLAINTEXT, IV, KEY) == CIPHERTEXT
        assert fernet._AES_CTR_decrypt(CIPHERTEXT, IV, KEY) == PLAINTEXT

        KEY = '7E24067817FAE0D743D6CE1F32539163'.decode('hex')
        IV = '006CB6DBC0543B59DA48D90B00000001'.decode('hex')
        PLAINTEXT = '000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F'.decode('hex')
        CIPHERTEXT = '5104A106168A72D9790D41EE8EDAD388EB2E1EFC46DA57C8FCE630DF9141BE28'.decode('hex')

        assert fernet._AES_CTR_encrypt(PLAINTEXT, IV, KEY) == CIPHERTEXT
        assert fernet._AES_CTR_decrypt(CIPHERTEXT, IV, KEY) == PLAINTEXT

        KEY = '7691BE035E5020A8AC6E618529F9A0DC'.decode('hex')
        IV = '00E0017B27777F3F4A1786F000000001'.decode('hex')
        PLAINTEXT = '000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F20212223'.decode('hex')
        CIPHERTEXT = 'C1CF48A89F2FFDD9CF4652E9EFDB72D74540A42BDE6D7836D59A5CEAAEF3105325B2072F'.decode('hex')

        assert fernet._AES_CTR_encrypt(PLAINTEXT, IV, KEY) == CIPHERTEXT
        assert fernet._AES_CTR_decrypt(CIPHERTEXT, IV, KEY) == PLAINTEXT
コード例 #12
0
ファイル: test_fernet.py プロジェクト: festoni/AES_CTR_CMAC
    def test_CTR_functionality(self):
        # test CTR functionality (decrypt(encrypt(msg)) == msg)
        key = Fernet.generate_key()
        fernet = Fernet(key)

        # test encrypt than decrypt gives back original message
        for i in range(20):
            data = os.urandom(i)
            key = os.urandom(16)
            iv = os.urandom(16)

            assert fernet._AES_CTR_decrypt(fernet._AES_CTR_encrypt(data, iv, key), iv, key) == data
コード例 #13
0
ファイル: projectconfig.py プロジェクト: Miguel-J/pineboo
    def save_projectxml(self, overwrite_existing: bool = True) -> None:
        """
        Save the connection.
        """
        profile = ET.Element("Profile")
        profile.set("Version", str(self.SAVE_VERSION))
        description = self.description
        filename = self.filename
        if not os.path.exists(self.profile_dir):
            os.mkdir(self.profile_dir)

        if not overwrite_existing and os.path.exists(filename):
            raise ProfileAlreadyExistsError

        passwDB = self.password or ""

        profile_user = ET.SubElement(profile, "profile-data")
        profile_password = ET.SubElement(profile_user, "password")
        profile_password.text = self.encodeProfilePasswordForVersion(
            self.project_password, self.SAVE_VERSION)
        if self.project_password and self.SAVE_VERSION > VERSION_1_1:
            key_salt = hashlib.sha256(profile_password.text.encode()).digest()
            key = hashlib.pbkdf2_hmac("sha256", self.project_password.encode(),
                                      key_salt, 10000)
            key64 = base64.urlsafe_b64encode(key)
            self.fernet = Fernet(key64)
        else:
            # Mask the password if no cipher is used!
            passwDB = base64.b64encode(passwDB.encode()).decode()
            self.fernet = None
        name = ET.SubElement(profile, "name")
        name.text = description
        dbs = ET.SubElement(profile, "database-server")
        self.createCipherSubElement(dbs, "type", text=self.type)
        self.createCipherSubElement(dbs, "host", text=self.host or "")
        self.createCipherSubElement(dbs,
                                    "port",
                                    text=str(self.port) if self.port else "")

        dbc = ET.SubElement(profile, "database-credentials")
        self.createCipherSubElement(dbc, "username", text=self.username or "")
        self.createCipherSubElement(dbc, "password", text=passwDB)

        self.createCipherSubElement(profile,
                                    "database-name",
                                    text=self.database)

        pretty_print_xml(profile)

        tree = ET.ElementTree(profile)

        tree.write(filename, xml_declaration=True, encoding="utf-8")
        self.version = self.SAVE_VERSION
コード例 #14
0
ファイル: test_fernet.py プロジェクト: festoni/AES_CTR_CMAC
    def test_subkey_generation(self):
        # test subkey generation using RFC test vectors
        key = Fernet.generate_key()
        fernet = Fernet(key)

        KEY = '2b7e151628aed2a6abf7158809cf4f3c'.decode('hex')
        AES_128 = '7df76b0c1ab899b33e42f047b91b546f'.decode('hex')
        K1 = 'fbeed618357133667c85e08f7236a8de'.decode('hex')
        K2 = 'f7ddac306ae266ccf90bc11ee46d513b'.decode('hex')

        K1_, K2_ = fernet._generate_subkey(KEY)
        assert K1 == K1_ and K2 == K2_
コード例 #15
0
ファイル: test_fernet.py プロジェクト: festoni/AES_CTR_CMAC
    def test_xor_bad_length(self):
        # test xor function when given mismatching lengths
        key = Fernet.generate_key()
        fernet = Fernet(key)

        # check xor functionality
        x = bytes(bytearray(16))
        for i in xrange(1, 20):
            if i == 16:
                continue
            y = os.urandom(i)
            with pytest.raises(AssertionError) as e:
                fernet._xor(x, y)
コード例 #16
0
def decrypt(filename, key):
    print("Decrypting...")

    f = Fernet(key)
    with open(filename, "rb") as fr:
        # read the encrypted data
        encrypted_data = fr.read()
    # decrypt data
    decrypted_data = f.decrypt(encrypted_data)
    # write the original file
    with open(filename, "wb") as fl:
        fl.write(decrypted_data)

    print("Finished")
    sys.exit()
コード例 #17
0
def create_access_ticket(session_key, ticket_owner_key, client_id):

    access_ticket_raw = {}

    access_ticket_raw['timeStamp'] = time.time()
    access_ticket_raw['client_id'] = client_id
    access_ticket_raw['duration'] = client_id
    access_ticket_raw['session_key'] = session_key
    access_ticket_raw['session_id'] = Fernet.generate_key()

    rad_encryptor_engine = Fernet(ticket_owner_key)
    access_ticket_enc = rad_encryptor_engine.encrypt(
        json.dumps(access_ticket_raw, cls=BytesDump).encode())

    return access_ticket_enc
コード例 #18
0
ファイル: test_fernet.py プロジェクト: festoni/AES_CTR_CMAC
    def test_CMAC_test_vectors(self):
        # test using official RFC AES_CMAC test vectors
        key = Fernet.generate_key()
        fernet = Fernet(key)

        K = '2b7e151628aed2a6abf7158809cf4f3c'.decode('hex')

        LENGTH = 0
        M = ''
        CMAC = 'bb1d6929e95937287fa37d129b756746'.decode('hex')
        assert fernet._AES_CMAC_generate(K, M, LENGTH) == CMAC

        LENGTH = 16
        M = '6bc1bee22e409f96e93d7e117393172a'.decode('hex')
        CMAC = '070a16b46b4d4144f79bdd9dd04a287c'.decode('hex')
        assert fernet._AES_CMAC_generate(K, M, LENGTH) == CMAC

        LENGTH = 40
        M = '6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411'.decode('hex')
        CMAC = 'dfa66747de9ae63030ca32611497c827'.decode('hex')
        assert fernet._AES_CMAC_generate(K, M, LENGTH) == CMAC

        LENGTH = 64
        M = '6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710'.decode('hex')
        CMAC = '51f0bebf7e3b9d92fc49741779363cfe'.decode('hex')
        assert fernet._AES_CMAC_generate(K, M, LENGTH) == CMAC
コード例 #19
0
ファイル: tests.py プロジェクト: zebpalmer/python-fernet
def test_fernet():
    current_time = int(time.time())
    iv = os.urandom(16)
    from cryptography.fernet import Fernet as CFernet

    salt = os.urandom(16)
    key = pbkdf2_hmac('sha256', b"password", salt, 100000, dklen=32)
    ckey = base64.urlsafe_b64encode(key)
    cfernet = CFernet(ckey)
    ccipher = cfernet._encrypt_from_parts(b"Secret message!", current_time, iv)

    fernet = Fernet(ckey)
    cipher = fernet._encrypt_from_parts(b"Secret message!", current_time, iv)
    assert cipher == ccipher
    ctext = cfernet.decrypt(ccipher)
    text = fernet.decrypt(cipher)

    assert ctext == text
コード例 #20
0
ファイル: test_fernet.py プロジェクト: festoni/AES_CTR_CMAC
    def test_CTR_decrypt(self):
        # test CTR decrypt function (encrypt with library API, decrypt with ours)
        key = Fernet.generate_key()
        fernet = Fernet(key)

        for i in range(20):
            data = os.urandom(i)
            key = os.urandom(16)
            iv = os.urandom(16)

            # encrypt with library APIs
            cipher = Cipher(algorithms.AES(key), modes.CTR(iv), backend=default_backend())
            encryptor = cipher.encryptor()
            ct = encryptor.update(data) + encryptor.finalize()

            # decrypt with our APIs
            pt = fernet._AES_CTR_decrypt(ct, iv, key)
            assert data == pt
コード例 #21
0
ファイル: test_fernet.py プロジェクト: festoni/AES_CTR_CMAC
    def test_CMAC_generate(self):
        # test AES_CMAC generation
        key = Fernet.generate_key()
        fernet = Fernet(key)

        # test against the cryptographi.io library APIs
        for i in range(20):
            M = os.urandom(i)
            K = os.urandom(16)

            # use library's API to generate CMAC
            c = cmac.CMAC(algorithms.AES(K), backend=default_backend())
            c.update(M)
            lib_cmac = c.finalize()

            # use our function to generate CMAC
            cmac_ = fernet._AES_CMAC_generate(K, M, len(M))

            # verify library CMAC vs our CMAC
            assert cmac_ == lib_cmac
コード例 #22
0
ファイル: test_fernet.py プロジェクト: festoni/AES_CTR_CMAC
    def test_CMAC_verify(self):
        # test CMAC verification function
        key = Fernet.generate_key()
        fernet = Fernet(key)

        # test against the cryptography.io library APIs
        for i in range(20):
            M = os.urandom(i)
            K = os.urandom(16)

            # use library API generation
            c = cmac.CMAC(algorithms.AES(K), backend=default_backend())
            c.update(M)
            lib_cmac = c.finalize()

            # verify a library generated cmac
            assert fernet._AES_CMAC_verify(K, M, len(M), lib_cmac)

            # verify against our own API
            cmac_ = fernet._AES_CMAC_generate(K, M, len(M))
            assert fernet._AES_CMAC_verify(K, M, len(M), cmac_)

            # # library verify our generated cmac
            c = cmac.CMAC(algorithms.AES(K), backend=default_backend())
            c.update(M)
            try:
                c.verify(cmac_)
            except Exception:
                raise Exception
コード例 #23
0
ファイル: fernet2.py プロジェクト: D-Speiser/cornell-tech
    def __init__(self, key, backend=None):
        if backend is None:
            backend = default_backend()
        try:
            self._fernet1 = Fernet(key, backend)
        except ValueError:
            self._fernet1 = None
        self._backend = backend

        key = base64.urlsafe_b64decode(key)
        hkey = hkdf.HKDF(algorithm=hashes.SHA256(), length=32, salt="0" * 16, info="", backend=backend)
        stretched_key = hkey.derive(key)
        self._signing_key, self._encryption_key = stretched_key[:16], stretched_key[16:]
コード例 #24
0
    def __init__(self, key, backend=None):
        if backend is None:
            backend = default_backend()

        # initialize a fernet object
        self._f = Fernet(key, backend=backend)

        key = base64.urlsafe_b64decode(key)
        if len(key) != 32:
            raise ValueError(
                "Fernet2 key must be 32 url-safe base64-encoded bytes.")

        h0 = HMAC(key, hashes.SHA256(), backend=backend)
        h1 = HMAC(key, hashes.SHA256(), backend=backend)
        #
        h0.update(b"0")
        h1.update(b"1")
        k0 = h0.finalize()[:16]
        k1 = h1.finalize()[:16]

        self._signing_key = k0
        self._encryption_key = k1
        self._backend = backend
コード例 #25
0
ファイル: test_fernet.py プロジェクト: festoni/AES_CTR_CMAC
    def test_timeout(self):
        # test exceeded time to live
        key = Fernet.generate_key()
        fernet = Fernet(key)

        ct = fernet.encrypt('Another secret message!')
        time.sleep(3)
        with pytest.raises(InvalidToken) as e:
            fernet.decrypt(ct, 2)
コード例 #26
0
ファイル: test_fernet.py プロジェクト: festoni/AES_CTR_CMAC
    def test_increment_integer(self):
        # test the increment integer function
        key = Fernet.generate_key()
        fernet = Fernet(key)

        # test normal behavior
        for i in range(100):
            assert fernet._increment_integer(i) == i + 1

        # test edge case
        i = 2**128-1
        assert fernet._increment_integer(i) == 0

        # test big integer
        with pytest.raises(AssertionError) as e:
            fernet._increment_integer(2**128)

        # test negative integer
        with pytest.raises(AssertionError) as e:
            fernet._increment_integer(-1)
コード例 #27
0
ファイル: test_fernet.py プロジェクト: festoni/AES_CTR_CMAC
    def test_bad_CMAC(self):
        # test bad CMAC signature
        key = Fernet.generate_key()
        fernet = Fernet(key)

        ct = fernet.encrypt('Aanother message!')
        ct = list(base64.urlsafe_b64decode(ct))     # decode ciphertext
        ct.append(b'\x00')                          # modify CMAC
        ct = ''.join(ct)
        ct = base64.urlsafe_b64encode(ct)           # encode ciphertext

        with pytest.raises(InvalidToken) as e:
            fernet.decrypt(ct)
コード例 #28
0
ファイル: test_fernet.py プロジェクト: festoni/AES_CTR_CMAC
    def test_bad_version(self):
        # test incorrect version of Fernet 0x91
        key = Fernet.generate_key()
        fernet = Fernet(key)

        ct = fernet.encrypt('Secret message!')
        ct = list(base64.urlsafe_b64decode(ct))     # decode ciphertext
        ct[0] = b'\x00'                             # change version
        ct = ''.join(ct)
        ct = base64.urlsafe_b64encode(ct)           # encode ciphertext

        with pytest.raises(InvalidToken) as e:
            fernet.decrypt(ct)
コード例 #29
0
    def _do_websocketserver_handshake(self):
        """
        Execute the websocket server handshake on the currently active websocket connection.

        The handshake is:
            - Get the protocol version from the server
            - Get the WebSocket server ID
            - Get the WebSocket server secret from Shotgun (used to encrypt the communications)

        This function validates the handshake by doing a dummy call to the server at the end
        of the handshake.
        """
        self._secret = None

        # Grab the protocol version from the running Shotgun WebSocket server
        protocol_version_resp = self._send_and_recv("get_protocol_version")
        self._protocol_version = json.loads(
            protocol_version_resp)["protocol_version"]

        # Grab the WebSocket server ID from the Shotgun WebSocket server
        server_id_resp = self._call_server_method("get_ws_server_id")
        self._server_id = json.loads(server_id_resp)["ws_server_id"]

        # Ask for the secret for this server id.
        response = self._shotgun_connection._call_rpc(
            "retrieve_ws_server_secret", {"ws_server_id": self._server_id})
        ws_server_secret = six.ensure_binary(response["ws_server_secret"])
        if ws_server_secret[-1:] != b"=":
            ws_server_secret += b"="

        self._secret = Fernet(ws_server_secret)

        # Make a dummy call to the server to make sure that the handshake is correctly done
        supported_command_repsp = self._call_server_method(
            "list_supported_commands")
        supported_commands = json.loads(supported_command_repsp).get(
            "reply", [])

        if "list_supported_commands" not in supported_commands:
            raise RuntimeError(
                "Unknown error in the websocket server handshake")
コード例 #30
0
ファイル: fernet2.py プロジェクト: NCEghtebas/cryptohw3
    def __init__(self, key, backend=None):
        if backend is None:
            backend = default_backend()

        # initialize a fernet object
        self._f = Fernet(key, backend=backend)

        key = base64.urlsafe_b64decode(key)
        if len(key) != 32:
            raise ValueError(
                "Fernet2 key must be 32 url-safe base64-encoded bytes."
            )

        h0 = HMAC(key, hashes.SHA256(), backend=backend)
        h1 = HMAC(key, hashes.SHA256(), backend=backend)
        # 
        h0 .update(b"0")
        h1 .update(b"1")
        k0 = h0.finalize()[:16]
        k1 = h1.finalize()[:16]

        self._signing_key = k0
        self._encryption_key = k1
        self._backend = backend
コード例 #31
0
ファイル: usuario.py プロジェクト: Demotoy-S-E/demotoy
 def __decrypt(self, token: bytes, key: bytes) -> bytes:
     return Fernet(key).decrypt(token)
コード例 #32
0
ファイル: usuario.py プロジェクト: Demotoy-S-E/demotoy
 def __encrypt(self, message: bytes, key: bytes) -> bytes:
     return Fernet(key).encrypt(message)
コード例 #33
0
ファイル: fernet2.py プロジェクト: NCEghtebas/cryptohw5
class Fernet2(object):
    def __init__(self, key, backend=None):
        if backend is None:
            backend = default_backend()
        try:
            self._fernet1 = Fernet(key, backend)
        except ValueError:
            self._fernet1 = None
        self._backend = backend

        key = base64.urlsafe_b64decode(key)
        hkey = hkdf.HKDF(algorithm=hashes.SHA256(), length=32,
                         salt='0'*16, info='', backend=backend)
        stretched_key = hkey.derive(key)
        self._signing_key, self._encryption_key = stretched_key[:16], stretched_key[16:]

    def SHA256hmac(self, key, data, sig=''):
        h = hmac.HMAC(key, hashes.SHA256(), backend=self._backend)
        h.update(data)
        if len(sig)>0:
            try:
                return h.verify(sig)
            except Exception as e:
                raise e
        else:
            return h.finalize()
        
    def _prf_hmac(self, key, data):
        out = self.SHA256hmac(key, data)
        while len(out)<len(data):
            out += self.SHA256hmac(key, out)
        return out[:len(data)]

    @classmethod
    def generate_key(cls):
        return base64.urlsafe_b64encode(os.urandom(32))

    def encrypt(self, data, associated_data=''):
        iv = os.urandom(16)
        return self._encrypt_from_parts(data, associated_data, iv)

    def _encrypt_from_parts(self, data, associated_data, iv):
        if not isinstance(data, bytes):
            raise TypeError("data must be bytes.")

        padder = padding.PKCS7(algorithms.AES.block_size).padder()
        padded_data = padder.update(data) + padder.finalize()
        encryptor = Cipher(
            algorithms.AES(self._encryption_key), modes.CBC(iv), self._backend
        ).encryptor()
        ciphertext = encryptor.update(padded_data) + encryptor.finalize()

        # MAC:  version || ad || iv || ctx
        basic_parts = (
            b"\x81" + bytes(associated_data) + iv + ciphertext
        )

        tag = self.SHA256hmac(self._signing_key, basic_parts)

        # return: version || iv || ctx || tag
        return base64.urlsafe_b64encode(b"\x81" + iv + ciphertext + tag)

    def decrypt(self, ctxt, ttl=None, associated_data=''):
        if not isinstance(ctxt, bytes):
            raise TypeError("ctxt must be bytes.")

        try:
            data = base64.urlsafe_b64decode(ctxt)
        except (TypeError, binascii.Error):
            raise InvalidToken
        
        if not data:
            raise InvalidToken

        # return: version || iv || ctx || tag
        if six.indexbytes(data, 0) == 0x80:
            # This is a Fernet1 (old version) ctx, handle accordingly
            try:
                msg = self._fernet1.decrypt(ctxt, ttl=ttl)
            except Exception:
                raise InvalidToken
            return msg
        elif six.indexbytes(data, 0) != 0x81:
            raise InvalidToken
        assert not debug or not ttl, "You are calling new fernet with ttl values."

        # First, verify the tag
        basic_parts = (
            b"\x81" + bytes(associated_data) + data[1:-32]
        )

        try:
            self.SHA256hmac(self._signing_key, basic_parts, sig=data[-32:])
        except InvalidSignature:
            raise InvalidToken

        # Now decrypt the text
        # version (1-byte) || iv (16-byte) || ctx || tag (32-byte)
        iv = data[1:17]
        ciphertext = data[17:-32]
        decryptor = Cipher(
            algorithms.AES(self._encryption_key), modes.CBC(iv), self._backend
        ).decryptor()
        plaintext_padded = decryptor.update(ciphertext)
        try:
            plaintext_padded += decryptor.finalize()
        except ValueError:
            raise InvalidToken
        unpadder = padding.PKCS7(algorithms.AES.block_size).unpadder()

        unpadded = unpadder.update(plaintext_padded)
        try:
            unpadded += unpadder.finalize()
        except ValueError:
            raise InvalidToken
        return unpadded
コード例 #34
0
ファイル: fernet2.py プロジェクト: NCEghtebas/cryptohw3
class Fernet2(object):
    def __init__(self, key, backend=None):
        if backend is None:
            backend = default_backend()

        # initialize a fernet object
        self._f = Fernet(key, backend=backend)

        key = base64.urlsafe_b64decode(key)
        if len(key) != 32:
            raise ValueError(
                "Fernet2 key must be 32 url-safe base64-encoded bytes."
            )

        h0 = HMAC(key, hashes.SHA256(), backend=backend)
        h1 = HMAC(key, hashes.SHA256(), backend=backend)
        # 
        h0 .update(b"0")
        h1 .update(b"1")
        k0 = h0.finalize()[:16]
        k1 = h1.finalize()[:16]

        self._signing_key = k0
        self._encryption_key = k1
        self._backend = backend

    @classmethod
    def generate_key(cls):
        return base64.urlsafe_b64encode(os.urandom(32))

    def encrypt(self, data, adata=""):
        # removed current time
        iv = os.urandom(16)
        return self._encrypt_from_parts(data, iv, adata)

    def _encrypt_from_parts(self, data, iv, adata=""):
        if not isinstance(data, bytes):
            raise TypeError("data must be bytes.")

        padder = padding.PKCS7(algorithms.AES.block_size).padder()
        padded_data = padder.update(data) + padder.finalize()
        encryptor = Cipher(
            algorithms.AES(self._encryption_key), modes.CBC(iv), self._backend
        ).encryptor()
        # ctx = AES( iv || msg )
        ctx = encryptor.update(padded_data) + encryptor.finalize()
        basic_parts = (
            b"\x81" + iv + ctx
        )
        # print(str(len(basic_parts)), "basic_parts_len == ", basic_parts)
        # print("iv = " + str(len(iv)), iv)
        # print(str(len(ctx)), "ctx == ", ctx)
        # print("adata == " , len(adata), adata)
        h = HMAC(self._signing_key, hashes.SHA256(), backend=self._backend)
        h.update(basic_parts+adata)
        # tag = HMAC( 0x81 || iv || ctx )
        tag = h.finalize()
        # print("tag = " , len(tag))
        return base64.urlsafe_b64encode( basic_parts + tag)

    def decrypt(self, token, ttl=None, adata=""):
        if not isinstance(token, bytes):
            raise TypeError("token must be bytes.")
        # print("token = ", token)

        try:
            data = base64.urlsafe_b64decode(token)
        except (TypeError, binascii.Error):
            raise InvalidToken
        # print("data = ", data)
        if not data or six.indexbytes(data, 0) == 0x80:
            print("80 version\n")
            # TODO: if 80:
            try:
                msg = self._f.decrypt(token, ttl)
                return msg
            except:
                raise InvalidToken

        elif not data or six.indexbytes(data, 0) == 0x81:
            # print("81 version\n")

            ############ VERIFYING adata
            # print("data = " + str(len(data)), data)
            h = HMAC(self._signing_key, hashes.SHA256(), backend=self._backend)
            basic_parts = data[:-32]
            basic_adata = basic_parts + bytes(adata)
            # print("==================", base64.urlsafe_b64decode(base64.urlsafe_b64encode(adata)))
            h.update(basic_adata)
            # print("basic_parts_len = " + str(len(basic_parts)), basic_parts)

            # print("basic_adata = " + str(len(basic_adata)), basic_adata)
            # print("adata = " , len(adata), adata)
            try:
                h.verify(data[-32:])
            except InvalidSignature:
                raise InvalidToken

            ################ signature stuff from fernet.py
            # h = HMAC(self._signing_key, hashes.SHA256(), backend=self._backend)
            # h.update(data[:-32]) # get everything from data except for last 32 bytes
            # # print(h.update(data[:-32]))
            # try:
            #     # verifying signature with the last 32 bytes
            #     h.verify(data[-32:])
            # except InvalidSignature:
            #     raise InvalidToken
            ################ END-OF signature stuff from fernet.py

            # iv = data[9:25]
            iv = data[1:17]
            # print("iv == " + str(len(iv)), iv)
            # find out associated data in data
            # try satement, if adata_to_get = adata
            ciphertext = data[17:-32]
            decryptor = Cipher(
                algorithms.AES(self._encryption_key), modes.CBC(iv), self._backend
            ).decryptor()
            plaintext_padded = decryptor.update(ciphertext)
            try:
                plaintext_padded += decryptor.finalize()
            except ValueError:
                raise InvalidToken
            unpadder = padding.PKCS7(algorithms.AES.block_size).unpadder()

            unpadded = unpadder.update(plaintext_padded)
            try:
                unpadded += unpadder.finalize()
            except ValueError:
                raise InvalidToken
            return unpadded

        else:
            raise InvalidToken