Exemple #1
0
    def generate_secure_text(self, origin_text: str) -> str:
        """
        Encrypt and sign the origin text by ``cryptography`` library
        using AES GCM algorithm.

        :arg origin_text: is a string that will be encrypted by the provided
            security secret.
        """

        iv = os.urandom(16)

        content = struct.pack(
            "l", int(time.time())) + ensure_bytes(origin_text)

        encryptor = AESCipher(
            aes_algorithms.AES(ensure_bytes(self.__security_secret)),
            aes_modes.GCM(iv),
            backend=aes_backend()
        ).encryptor()

        ciphertext = encryptor.update(content) + encryptor.finalize()

        final_encrypted_text = iv
        final_encrypted_text += struct.pack("l", len(ciphertext))
        final_encrypted_text += ciphertext
        final_encrypted_text += encryptor.tag

        return ensure_str(base64.b64encode(final_encrypted_text))
Exemple #2
0
    def lookup_origin_text(
        self, secure_text: str,
            valid_length: Optional[int]=None) -> str:
        try:
            encrypted_text_reader = io.BytesIO(base64.b64decode(secure_text))
        except:  # Unable to decode the data.
            return None

        try:
            iv = encrypted_text_reader.read(16)
            length = struct.unpack("l", encrypted_text_reader.read(8))[0]
            ciphertext = encrypted_text_reader.read(length)
            tag = encrypted_text_reader.read(16)
        except:  # Unable to split the data.
            return None

        decryptor = AESCipher(
            aes_algorithms.AES(self._security_secret),
            aes_modes.GCM(iv, tag),
            backend=aes_backend()
        ).decryptor()

        try:
            content = decryptor.update(ciphertext) + decryptor.finalize()
        except:  # Unable to decrypt and/or verify the data.
            return None

        timestamp = struct.unpack("l", content[:8])[0]
        text = content[8:]

        if valid_length and int(time.time()) - timestamp > valid_length:
            return None  # Data Expired.

        return ensure_str(text)
Exemple #3
0
    def lookup_origin_text(self, secure_text: str,
                           valid_length: int=None) -> str:
        """
        Decrypt the encrypted text, validate the signature and
        return the origin text. If the content and the signature mismatches,
        ``None`` will be returned.

        :arg secure_text: is a base64 encoded string, which contains
            the generated time, the content, and a AES GCM tag.
        :arg valid_length: the length that the content should be valid.
            The unit is second. It you want the content be always valid, set
            the length to ``None``.
        """

        encrypted_text_reader = io.BytesIO(base64.b64decode(secure_text))

        iv = encrypted_text_reader.read(16)
        length = struct.unpack("l", encrypted_text_reader.read(8))[0]
        ciphertext = encrypted_text_reader.read(length)
        tag = encrypted_text_reader.read(16)

        decryptor = AESCipher(
            aes_algorithms.AES(ensure_bytes(self.__security_secret)),
            aes_modes.GCM(iv, tag),
            backend=aes_backend()
        ).decryptor()

        try:
            content = decryptor.update(ciphertext) + decryptor.finalize()
        except:
            return None

        timestamp = struct.unpack("l", content[:8])[0]
        text = content[8:]

        if valid_length and int(time.time()) - timestamp > valid_length:
            return None

        try:
            return ensure_str(text)
        except:
            return None
Exemple #4
0
    def generate_secure_text(self, origin_text: str) -> str:
        if not isinstance(origin_text, str):
            raise TypeError("origin_text should be a string.")

        iv = os.urandom(16)

        content = struct.pack("l", int(time.time()))
        content += ensure_bytes(origin_text)

        encryptor = AESCipher(
            aes_algorithms.AES(self._security_secret),
            aes_modes.GCM(iv),
            backend=aes_backend()
        ).encryptor()

        ciphertext = encryptor.update(content) + encryptor.finalize()

        final_encrypted_text = iv
        final_encrypted_text += struct.pack("l", len(ciphertext))
        final_encrypted_text += ciphertext
        final_encrypted_text += encryptor.tag

        return ensure_str(base64.b64encode(final_encrypted_text))