当前位置: 首页>>代码示例>>Python>>正文


Python MultiFernet.encrypt方法代码示例

本文整理汇总了Python中cryptography.fernet.MultiFernet.encrypt方法的典型用法代码示例。如果您正苦于以下问题:Python MultiFernet.encrypt方法的具体用法?Python MultiFernet.encrypt怎么用?Python MultiFernet.encrypt使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在cryptography.fernet.MultiFernet的用法示例。


在下文中一共展示了MultiFernet.encrypt方法的11个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的Python代码示例。

示例1: test_rotate_decrypt_no_shared_keys

# 需要导入模块: from cryptography.fernet import MultiFernet [as 别名]
# 或者: from cryptography.fernet.MultiFernet import encrypt [as 别名]
    def test_rotate_decrypt_no_shared_keys(self, backend):
        f1 = Fernet(base64.urlsafe_b64encode(b"\x00" * 32), backend=backend)
        f2 = Fernet(base64.urlsafe_b64encode(b"\x01" * 32), backend=backend)

        mf1 = MultiFernet([f1])
        mf2 = MultiFernet([f2])

        with pytest.raises(InvalidToken):
            mf2.rotate(mf1.encrypt(b"abc"))
开发者ID:amauryfa,项目名称:cryptography,代码行数:11,代码来源:test_fernet.py

示例2: test_rotate

# 需要导入模块: from cryptography.fernet import MultiFernet [as 别名]
# 或者: from cryptography.fernet.MultiFernet import encrypt [as 别名]
    def test_rotate(self, backend):
        f1 = Fernet(base64.urlsafe_b64encode(b"\x00" * 32), backend=backend)
        f2 = Fernet(base64.urlsafe_b64encode(b"\x01" * 32), backend=backend)

        mf1 = MultiFernet([f1])
        mf2 = MultiFernet([f2, f1])

        plaintext = b"abc"
        mf1_ciphertext = mf1.encrypt(plaintext)

        assert mf2.decrypt(mf1_ciphertext) == plaintext

        rotated = mf2.rotate(mf1_ciphertext)

        assert rotated != mf1_ciphertext
        assert mf2.decrypt(rotated) == plaintext

        with pytest.raises(InvalidToken):
            mf1.decrypt(rotated)
开发者ID:amauryfa,项目名称:cryptography,代码行数:21,代码来源:test_fernet.py

示例3: test_rotate_preserves_timestamp

# 需要导入模块: from cryptography.fernet import MultiFernet [as 别名]
# 或者: from cryptography.fernet.MultiFernet import encrypt [as 别名]
    def test_rotate_preserves_timestamp(self, backend, monkeypatch):
        f1 = Fernet(base64.urlsafe_b64encode(b"\x00" * 32), backend=backend)
        f2 = Fernet(base64.urlsafe_b64encode(b"\x01" * 32), backend=backend)

        mf1 = MultiFernet([f1])
        mf2 = MultiFernet([f2, f1])

        plaintext = b"abc"
        mf1_ciphertext = mf1.encrypt(plaintext)

        later = datetime.datetime.now() + datetime.timedelta(minutes=5)
        later_time = time.mktime(later.timetuple())
        monkeypatch.setattr(time, "time", lambda: later_time)

        original_time, _ = Fernet._get_unverified_token_data(mf1_ciphertext)
        rotated_time, _ = Fernet._get_unverified_token_data(
            mf2.rotate(mf1_ciphertext)
        )

        assert later_time != rotated_time
        assert original_time == rotated_time
开发者ID:amauryfa,项目名称:cryptography,代码行数:23,代码来源:test_fernet.py

示例4: EncryptingPacker

# 需要导入模块: from cryptography.fernet import MultiFernet [as 别名]
# 或者: from cryptography.fernet.MultiFernet import encrypt [as 别名]
class EncryptingPacker(object):
    """Implement conversion of Python objects to/from encrypted bytestrings.

    :param str key: a `Fernet`_ key to use for encryption and decryption
    :param list old_keys: additional `Fernet`_ keys to use for decryption

    .. note::

        Encrypted messages contain the timestamp at which they were generated
        *in plaintext*. See `our audit`_ for discussion of this and other
        considerations with `Fernet`_.

    .. _Fernet: https://cryptography.io/en/latest/fernet/
    .. _our audit: https://github.com/gratipay/gratipay.com/pull/3998#issuecomment-216227070

    """

    def __init__(self, key, *old_keys):
        keys = [key] + list(old_keys)
        self.fernet = MultiFernet([Fernet(k) for k in keys])

    def pack(self, obj):
        """Given a JSON-serializable object, return a `Fernet`_ token.
        """
        obj = json.dumps(obj)           # serialize to unicode
        obj = obj.encode('utf8')        # convert to bytes
        obj = self.fernet.encrypt(obj)  # encrypt
        return obj

    def unpack(self, token):
        """Given a `Fernet`_ token with JSON in the ciphertext, return a Python object.
        """
        obj = token
        if not type(obj) is bytes:
            raise TypeError("need bytes, got {}".format(type(obj)))
        obj = self.fernet.decrypt(obj)  # decrypt
        obj = obj.decode('utf8')        # convert to unicode
        obj = json.loads(obj)           # deserialize from unicode
        return obj
开发者ID:PeterDaveHello,项目名称:gratipay.com,代码行数:41,代码来源:crypto.py

示例5: AutopushSettings

# 需要导入模块: from cryptography.fernet import MultiFernet [as 别名]
# 或者: from cryptography.fernet.MultiFernet import encrypt [as 别名]

#.........这里部分代码省略.........
            returnValue(False)

        # Get tables for the new month, and verify they exist before we try to
        # switch over
        message_table = yield deferToThread(get_rotating_message_table,
                                            self._message_prefix)

        # Both tables found, safe to switch-over
        self.current_month = today.month
        self.current_msg_month = message_table.table_name
        self.message_tables[self.current_msg_month] = \
            Message(message_table, self.metrics)
        returnValue(True)

    def update(self, **kwargs):
        """Update the arguments, if a ``crypto_key`` is in kwargs then the
        ``self.fernet`` attribute will be initialized"""
        for key, val in kwargs.items():
            if key == "crypto_key":
                fkeys = []
                if not isinstance(val, list):
                    val = [val]
                for v in val:
                    fkeys.append(Fernet(v))
                self.fernet = MultiFernet(fkeys)
            else:
                setattr(self, key, val)

    def make_simplepush_endpoint(self, uaid, chid):
        """Create a simplepush endpoint"""
        root = self.endpoint_url + "/spush/"
        base = (uaid.replace('-', '').decode("hex") +
                chid.replace('-', '').decode("hex"))
        return root + 'v1/' + self.fernet.encrypt(base).strip('=')

    def make_endpoint(self, uaid, chid, key=None):
        """Create an v1 or v2 WebPush endpoint from the identifiers.

        Both endpoints use bytes instead of hex to reduce ID length.
        v0 is uaid.hex + ':' + chid.hex and is deprecated.
        v1 is the uaid + chid
        v2 is the uaid + chid + sha256(key).bytes

        :param uaid: User Agent Identifier
        :param chid: Channel or Subscription ID
        :param key: Optional Base64 URL-encoded application server key
        :returns: Push endpoint

        """
        root = self.endpoint_url + '/push/'
        base = (uaid.replace('-', '').decode("hex") +
                chid.replace('-', '').decode("hex"))

        if key is None:
            return root + 'v1/' + self.fernet.encrypt(base).strip('=')

        raw_key = base64url_decode(key.encode('utf8'))
        ep = self.fernet.encrypt(base + sha256(raw_key).digest()).strip('=')
        return root + 'v2/' + ep

    def parse_endpoint(self, token, version="v0", ckey_header=None):
        """Parse an endpoint into component elements of UAID, CHID and optional
        key hash if v2

        :param token: The obscured subscription data.
        :param version: This is the API version of the token.
开发者ID:adamchainz,项目名称:autopush,代码行数:70,代码来源:settings.py

示例6: AutopushSettings

# 需要导入模块: from cryptography.fernet import MultiFernet [as 别名]
# 或者: from cryptography.fernet.MultiFernet import encrypt [as 别名]

#.........这里部分代码省略.........
            self.metrics = TwistedMetrics(statsd_host, statsd_port)
        else:
            self.metrics = SinkMetrics()
        if not crypto_key:
            crypto_key = [Fernet.generate_key()]
        if not isinstance(crypto_key, list):
            crypto_key = [crypto_key]
        self.update(crypto_key=crypto_key)
        self.crypto_key = crypto_key

        if auth_key is None:
            auth_key = []
        if not isinstance(auth_key, list):
            auth_key = [auth_key]
        self.auth_key = auth_key

        self.max_data = max_data
        self.clients = {}

        # Setup hosts/ports/urls
        default_hostname = socket.gethostname()
        self.hostname = hostname or default_hostname
        if resolve_hostname:
            self.hostname = resolve_ip(self.hostname)

        self.port = port
        self.endpoint_hostname = endpoint_hostname or self.hostname
        self.router_hostname = router_hostname or self.hostname

        self.router_conf = router_conf
        self.router_url = canonical_url(
            router_scheme or 'http',
            self.router_hostname,
            router_port
        )

        self.endpoint_url = canonical_url(
            endpoint_scheme or 'http',
            self.endpoint_hostname,
            endpoint_port
        )

        # Database objects
        self.router_table = get_router_table(router_tablename,
                                             router_read_throughput,
                                             router_write_throughput)
        self.storage_table = get_storage_table(storage_tablename,
                                               storage_read_throughput,
                                               storage_write_throughput)
        self.message_table = get_message_table(message_tablename,
                                               message_read_throughput,
                                               message_write_throughput)
        self.storage = Storage(self.storage_table, self.metrics)
        self.router = Router(self.router_table, self.metrics)
        self.message = Message(self.message_table, self.metrics)

        # Run preflight check
        preflight_check(self.storage, self.router)

        # CORS
        self.cors = enable_cors

        # Force timeout in idle seconds
        self.wake_timeout = wake_timeout

        # Setup the routers
        self.routers = {}
        self.routers["simplepush"] = SimpleRouter(
            self,
            router_conf.get("simplepush")
        )
        self.routers["webpush"] = WebPushRouter(self, None)
        if 'apns' in router_conf:
            self.routers["apns"] = APNSRouter(self, router_conf["apns"])
        if 'gcm' in router_conf:
            self.routers["gcm"] = GCMRouter(self, router_conf["gcm"])

        # Env
        self.env = env

        self.hello_timeout = hello_timeout

    def update(self, **kwargs):
        """Update the arguments, if a ``crypto_key`` is in kwargs then the
        ``self.fernet`` attribute will be initialized"""
        for key, val in kwargs.items():
            if key == "crypto_key":
                fkeys = []
                if not isinstance(val, list):
                    val = [val]
                for v in val:
                    fkeys.append(Fernet(v))
                self.fernet = MultiFernet(fkeys)
            else:
                setattr(self, key, val)

    def make_endpoint(self, uaid, chid):
        """ Create an endpoint from the identifiers"""
        return self.endpoint_url + '/push/' + \
            self.fernet.encrypt((uaid + ':' + chid).encode('utf8'))
开发者ID:ncalexan,项目名称:autopush,代码行数:104,代码来源:settings.py

示例7: test_encrypt

# 需要导入模块: from cryptography.fernet import MultiFernet [as 别名]
# 或者: from cryptography.fernet.MultiFernet import encrypt [as 别名]
    def test_encrypt(self, backend):
        f1 = Fernet(base64.urlsafe_b64encode(b"\x00" * 32), backend=backend)
        f2 = Fernet(base64.urlsafe_b64encode(b"\x01" * 32), backend=backend)
        f = MultiFernet([f1, f2])

        assert f1.decrypt(f.encrypt(b"abc")) == b"abc"
开发者ID:amauryfa,项目名称:cryptography,代码行数:8,代码来源:test_fernet.py

示例8: RedisChannelLayer

# 需要导入模块: from cryptography.fernet import MultiFernet [as 别名]
# 或者: from cryptography.fernet.MultiFernet import encrypt [as 别名]
class RedisChannelLayer(BaseChannelLayer):
    """
    ORM-backed channel environment. For development use only; it will span
    multiple processes fine, but it's going to be pretty bad at throughput.
    """

    blpop_timeout = 5

    def __init__(self, expiry=60, hosts=None, prefix="asgi:", group_expiry=86400, capacity=100, channel_capacity=None,
                 symmetric_encryption_keys=None):
        super(RedisChannelLayer, self).__init__(
            expiry=expiry,
            group_expiry=group_expiry,
            capacity=capacity,
            channel_capacity=channel_capacity,
        )
        # Make sure they provided some hosts, or provide a default
        if not hosts:
            hosts = [("localhost", 6379)]
        self.hosts = []
        for entry in hosts:
            if isinstance(entry, six.string_types):
                self.hosts.append(entry)
            else:
                self.hosts.append("redis://%s:%d/0" % (entry[0],entry[1]))
        self.prefix = prefix
        assert isinstance(self.prefix, six.text_type), "Prefix must be unicode"
        # Precalculate some values for ring selection
        self.ring_size = len(self.hosts)
        self.ring_divisor = int(math.ceil(4096 / float(self.ring_size)))
        # Create connections ahead of time (they won't call out just yet, but
        # we want to connection-pool them later)
        self._connection_list = [
            redis.Redis.from_url(host)
            for host in self.hosts
        ]
        # Decide on a unique client prefix to use in ! sections
        # TODO: ensure uniqueness better, e.g. Redis keys with SETNX
        self.client_prefix = "".join(random.choice(string.ascii_letters) for i in range(8))
        # Register scripts
        connection = self.connection(None)
        self.chansend = connection.register_script(self.lua_chansend)
        self.lpopmany = connection.register_script(self.lua_lpopmany)
        self.delprefix = connection.register_script(self.lua_delprefix)
        # See if we can do encryption if they asked
        if symmetric_encryption_keys:
            if isinstance(symmetric_encryption_keys, six.string_types):
                raise ValueError("symmetric_encryption_keys must be a list of possible keys")
            try:
                from cryptography.fernet import MultiFernet
            except ImportError:
                raise ValueError("Cannot run with encryption without 'cryptography' installed.")
            sub_fernets = [self.make_fernet(key) for key in symmetric_encryption_keys]
            self.crypter = MultiFernet(sub_fernets)
        else:
            self.crypter = None

    ### ASGI API ###

    extensions = ["groups", "flush"]

    def send(self, channel, message):
        # Typecheck
        assert isinstance(message, dict), "message is not a dict"
        assert self.valid_channel_name(channel), "Channel name not valid"
        # Write out message into expiring key (avoids big items in list)
        # TODO: Use extended set, drop support for older redis?
        message_key = self.prefix + uuid.uuid4().hex
        channel_key = self.prefix + channel
        # Pick a connection to the right server - consistent for response
        # channels, random for normal channels
        if "!" in channel or "?" in channel:
            index = self.consistent_hash(channel)
            connection = self.connection(index)
        else:
            connection = self.connection(None)
        # Use the Lua function to do the set-and-push
        try:
            self.chansend(
                keys=[message_key, channel_key],
                args=[self.serialize(message), self.expiry, self.get_capacity(channel)],
            )
        except redis.exceptions.ResponseError as e:
            # The Lua script handles capacity checking and sends the "full" error back
            if e.args[0] == "full":
                raise self.ChannelFull

    def receive_many(self, channels, block=False):
        if not channels:
            return None, None
        channels = list(channels)
        assert all(self.valid_channel_name(channel) for channel in channels), "One or more channel names invalid"
        # Work out what servers to listen on for the given channels
        indexes = {}
        random_index = self.random_index()
        for channel in channels:
            if "!" in channel or "?" in channel:
                indexes.setdefault(self.consistent_hash(channel), []).append(channel)
            else:
                indexes.setdefault(random_index, []).append(channel)
#.........这里部分代码省略.........
开发者ID:MisaGu,项目名称:chess,代码行数:103,代码来源:core.py

示例9: AutopushSettings

# 需要导入模块: from cryptography.fernet import MultiFernet [as 别名]
# 或者: from cryptography.fernet.MultiFernet import encrypt [as 别名]

#.........这里部分代码省略.........

        # Used to determine whether a connection is out of date with current
        # db objects
        self.current_msg_month = make_rotating_tablename(self._message_prefix)
        self.current_month = datetime.date.today().month
        self.create_initial_message_tables()

        # Run preflight check
        preflight_check(self.storage, self.router)

        # CORS
        self.cors = enable_cors

        # Force timeout in idle seconds
        self.wake_timeout = wake_timeout

        # Setup the routers
        self.routers = {}
        self.routers["simplepush"] = SimpleRouter(
            self,
            router_conf.get("simplepush")
        )
        self.routers["webpush"] = WebPushRouter(self, None)
        if 'apns' in router_conf:
            self.routers["apns"] = APNSRouter(self, router_conf["apns"])
        if 'gcm' in router_conf:
            self.routers["gcm"] = GCMRouter(self, router_conf["gcm"])

        # Env
        self.env = env

        self.hello_timeout = hello_timeout

    @property
    def message(self):
        """Property that access the current message table"""
        return self.message_tables[self.current_msg_month]

    @message.setter
    def message(self, value):
        """Setter to set the current message table"""
        self.message_tables[self.current_msg_month] = value

    def create_initial_message_tables(self):
        """Initializes a dict of the initial rotating messages tables.

        An entry for last months table, and an entry for this months table.

        """
        last_month = get_rotating_message_table(self._message_prefix, -1)
        this_month = get_rotating_message_table(self._message_prefix)
        self.message_tables = {
            last_month.table_name: Message(last_month, self.metrics),
            this_month.table_name: Message(this_month, self.metrics),
        }

    @inlineCallbacks
    def update_rotating_tables(self):
        """This method is intended to be tasked to run periodically off the
        twisted event hub to rotate tables.

        When today is a new month from yesterday, then we swap out all the
        table objects on the settings object.

        """
        today = datetime.date.today()
        if today.month == self.current_month:
            # No change in month, we're fine.
            returnValue(False)

        # Get tables for the new month, and verify they exist before we try to
        # switch over
        message_table = yield deferToThread(get_rotating_message_table,
                                            self._message_prefix)

        # Both tables found, safe to switch-over
        self.current_month = today.month
        self.current_msg_month = message_table.table_name
        self.message_tables[self.current_msg_month] = \
            Message(message_table, self.metrics)
        returnValue(True)

    def update(self, **kwargs):
        """Update the arguments, if a ``crypto_key`` is in kwargs then the
        ``self.fernet`` attribute will be initialized"""
        for key, val in kwargs.items():
            if key == "crypto_key":
                fkeys = []
                if not isinstance(val, list):
                    val = [val]
                for v in val:
                    fkeys.append(Fernet(v))
                self.fernet = MultiFernet(fkeys)
            else:
                setattr(self, key, val)

    def make_endpoint(self, uaid, chid):
        """ Create an endpoint from the identifiers"""
        return self.endpoint_url + '/push/' + \
            self.fernet.encrypt((uaid + ':' + chid).encode('utf8'))
开发者ID:tomzhang,项目名称:autopush,代码行数:104,代码来源:settings.py

示例10: __init__

# 需要导入模块: from cryptography.fernet import MultiFernet [as 别名]
# 或者: from cryptography.fernet.MultiFernet import encrypt [as 别名]
class SecretStore:
    def __init__(self, *master_keys, encrypted_store: dict = None):
        if not len(master_keys):
            raise ValueError('at least one master key must be passed')
        self.crypt = MultiFernet([Fernet(key) for key in master_keys])
        if not encrypted_store:
            self.encrypted_store = dict()
        else:
            self.encrypted_store = encrypted_store

    @staticmethod
    def generate_master_key():
        return Fernet.generate_key()

    @staticmethod
    def add_master_key(key_yaml_path):
        master_key = SecretStore.generate_master_key()
        try:
            master_keys = SecretStore._load_keys(key_yaml_path)
        except OSError:
            master_keys = []
        master_keys = [master_key] + master_keys
        SecretStore._save_as_yaml(key_yaml_path, 'keys', master_keys)
        return master_keys

    @staticmethod
    def _load_keys(key_yaml_path):
        with open(key_yaml_path, 'r') as key_file:
            master_keys = yaml.load(key_file)['keys']
            return master_keys

    @classmethod
    def load_from_yaml(cls, key_yaml_path, store_yaml_path=None, encrypted=True):
        master_keys = SecretStore._load_keys(key_yaml_path)
        secret_store = cls(*master_keys)
        if store_yaml_path:
            secret_store.load_as_yaml(store_yaml_path, encrypted=encrypted)
        return secret_store

    def encrypt_copy(self, plain_store, *path):
        for key in plain_store:
            value = plain_store[key]
            if isinstance(value, bytes) or isinstance(value, str):
                self.set_secret(value, *path, key)
            else:
                self.encrypt_copy(value, *(list(path) + [key]))

    def set_secret(self, secret, *path):
        if not len(path):
            raise ValueError('path to secret must not be empty')
        if not (isinstance(secret, bytes) or isinstance(secret, str)):
            raise ValueError(
                'secret must be bytes or str, but {0} is passed'.format(
                    type(secret)))
        if isinstance(secret, str):
            secret = secret.encode('utf-8')
        encrypted_secret = self.crypt.encrypt(secret)
        store = self.encrypted_store
        for key in path[:-1]:
            store = store.setdefault(key, dict())
        store[path[-1]] = encrypted_secret

    def get_secret(self, *path):
        encrypted_secret = self.get_encrypted_secret(*path)
        return self.crypt.decrypt(encrypted_secret)

    def delete_secret(self, *path):
        if not len(path):
            raise ValueError('path to secret must not be empty')
        store = self.encrypted_store
        for key in path[:-1]:
            store = store[key]
        del store[path[-1]]

    def get_encrypted_secret(self, *path):
        if not len(path):
            raise ValueError('path to secret must not be empty')
        store = self.encrypted_store
        for key in path[:-1]:
            store = store[key]
        encrypted_secret = store[path[-1]]
        return encrypted_secret

    def load_as_yaml(self, yaml_path, encrypted=True):
        with open(yaml_path, 'r') as secret_file:
            secret_storage = yaml.load(secret_file)
            if encrypted:
                self.encrypted_store = secret_storage['encrypted_store']
            else:
                self.encrypt_copy(secret_storage['encrypted_store'])

    def save_as_yaml(self, yaml_path):
        SecretStore._save_as_yaml(yaml_path, 'encrypted_store', self.encrypted_store)

    def print_as_yaml(self):
        print(yaml.dump(self.encrypted_store, default_flow_style=False))

    @staticmethod
    def _wrap_payload(payload_key, payload):
        now = datetime.now()
#.........这里部分代码省略.........
开发者ID:ashapochka,项目名称:saapy,代码行数:103,代码来源:secret_store.py

示例11: Cryptograph

# 需要导入模块: from cryptography.fernet import MultiFernet [as 别名]
# 或者: from cryptography.fernet.MultiFernet import encrypt [as 别名]
class Cryptograph(object):
    """Symmetric encryption and decryption for the storage of sensitive data.

    We currently rely on Fernet, which was the algorithm adopted by Gratipay:
    https://github.com/gratipay/gratipay.com/pull/3998#issuecomment-216227070

    For encryption Fernet uses the AES cipher in CBC mode with PKCS7 padding and
    a 128 bits key. For authentication it uses HMAC-SHA256 with another 128 bits
    key.

    Fernet messages contain the timestamp at which they were generated *in plain
    text*. This isn't a problem for us since we want to store the time at which
    the data was encrypted in order to facilitate key rotation.

    We use CBOR (Concise Binary Object Representation) to serialize objects
    before encryption. Compared to JSON, CBOR is faster to parse and serialize,
    more compact, and extensible (it can represent any data type using "tags").
    More info on CBOR: http://cbor.io/ https://tools.ietf.org/html/rfc7049
    """

    KEY_ROTATION_DELAY = timedelta(weeks=1)

    def __init__(self):
        if website.env.aws_secret_access_key:
            sm = self.secrets_manager = boto3.client('secretsmanager', region_name='eu-west-1')
            secret = sm.get_secret_value(SecretId='Fernet')
            rotation_start = secret['CreatedDate'].date()
            keys = secret['SecretString'].split()
        else:
            self.secrets_manager = None
            parts = os.environ['SECRET_FERNET_KEYS'].split()
            rotation_start = date(*map(int, parts[0].split('-')))
            keys = parts[1:]
        self.fernet_rotation_start = rotation_start
        self.fernet_keys = [k.encode('ascii') for k in keys]
        self.fernet = MultiFernet([Fernet(k) for k in self.fernet_keys])

    def encrypt_dict(self, dic, allow_single_key=False):
        """Serialize and encrypt a dictionary for storage in the database.

        Encrypting partially predictable data may help an attacker break the
        encryption key, so to make our data less predictable we randomize the
        order of the dict's items before serializing it.

        For this to be effective the CBOR serializer must not sort the items
        again in an attempt to produce Canonical CBOR, so we explicitly pass
        `canonical=False` to the `cbor.dumps` function.

        In addition, the dict must not contain only one key if that key is
        predictable, so a `CryptoWarning` is emitted when `dic` only contains
        one key, unless `allow_single_key` is set to `True`.
        """
        dic = self.randomize_dict(dic, allow_single_key=allow_single_key)
        serialized = cbor.dumps(dic, canonical=False)
        encrypted = self.fernet.encrypt(serialized)
        return Encrypted(dict(scheme='fernet', payload=encrypted, ts=utcnow()))

    def decrypt(self, scheme, payload):
        """Decrypt and reconstruct an object stored in the database.
        """
        if scheme == 'fernet':
            decrypted = self.fernet.decrypt(payload)
        else:
            raise ValueError('unknown encryption scheme %r' % scheme)
        return cbor.loads(decrypted)

    @staticmethod
    def randomize_dict(dic, allow_single_key=False):
        """Randomize the order of a dictionary's items.

        Emits a `CryptoWarning` if `dic` only contains one key, unless
        `allow_single_key` is set to `True`.
        """
        if not isinstance(dic, dict):
            raise TypeError("expected a dict, got %s" % type(dic))
        # Compute the number of random bytes needed based on the size of the dict
        n = len(dic)
        if n < 2:
            # Can't randomize the order if the dict contains less than 2 items
            if n == 1 and not allow_single_key:
                warnings.warn("dict only contains one key", CryptoWarning)
            return dic
        n = int(log(n, 2) // 8) + 2
        # Return a new ordered dict sorted randomly
        return OrderedDict(
            t[1] for t in sorted((urandom(n), item) for item in dic.items())
        )

    def rotate_key(self):
        """Generate a new key and send it to the secrets manager.
        """
        keys = b' '.join([Fernet.generate_key()] + self.fernet_keys).decode()
        if self.secrets_manager:
            self.secrets_manager.update_secret(SecretId='Fernet', SecretString=keys)
        else:
            keys = utcnow().date().isoformat() + ' ' + keys
            print("No secrets manager, updating the key storage is up to you.")
        return keys

    def rotate_message(self, msg, force=False):
#.........这里部分代码省略.........
开发者ID:liberapay,项目名称:liberapay.com,代码行数:103,代码来源:crypto.py


注:本文中的cryptography.fernet.MultiFernet.encrypt方法示例由纯净天空整理自Github/MSDocs等开源代码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。