当前位置:手机游戏 > 手游资讯 > 游戏攻略 > 密码库((02)Python密码库Cryptography探究学习---深入理解Fern)

密码库((02)Python密码库Cryptography探究学习---深入理解Fern)

作者:哪吒游戏网 来源:哪吒游戏网 2020-05-26 10:21:15

密码库((02)Python密码库Cryptography探究学习---深入理解Fern),哪吒游戏网给大家带来详细的密码库((02)Python密码库Cryptography探究学习---深入理解Fern)介绍,大家可以阅读一下,希望这篇密码库((02)Python密码库Cryptography探究学习---深入理解Fern)可以给你带来参考价值。

本节对Fernet进行深入介绍,使读者能够理解cryptographic recipes的含义,能在实践中正确使用密码学的相关算法。

Fernet不仅仅是个对称密码算法,它是密码学原语的集合应用,主要有3个特点:(1)使用了符合密码安全的随机数密钥。(2)提供了加密功能:使用了128位密钥的AES加密算法,对数据 PKCS7 填充后,以AES-CBC模式进行加密。(3)提供了认证的功能,采用Sha256的哈希函数,产生消息认证码(HMAC)。

大家先通过github.com/pyca/cryptography/blob/master/src/cryptography/fernet.py,结合源代码,看看下面的详细介绍:

一、使用了密码安全的随机数密钥

对于密码算法而言,密钥应该是符合密码学安全的随机数。只有这样才能保证密码算法的安全性密码库,否则容易遭受攻击。在很多应用中,密钥并不随机,不能符合密码学的要求,存在着漏洞。

那么如何得到真正的随机数呢?真正的随机数是通过物理过程得到的,比如抛硬币、掷骰子,布朗运动,量子效应,放射性衰变,振荡器采样等。

通过计算法的方式得到真正的随机数,是几乎不可能的。冯.诺依曼说过:“任何人考虑用数学的方法产生随机数肯定是不合情理的”。一般而言,大家经常用到的随机数生成函数,并不能真正的产生随机数,也不能用在密码学算法中,比如C语言中的rand()函数,它通过如下的函数计算而来。

能密码算法中使用的随机数,如何产生呢?建议采用操作系统中的随机数产生器来产生,在Unix操作系统中使用 /dev/urandom,而在Windows操作系统中使用CryptGenRandom 生成。由于我们使用Python语言,只需要使用如下的方法,即

>>> import os
>>> salt = os.urandom(32)

我们通过15.1. os - Miscellaneous operating system interfaces - Python 2.7.13 documentation,来查看os.urandom(n)的说明。

Return a string of n random bytes suitable for cryptographic use.

This function returns random bytes from an OS-specific randomness source. The returned data should be unpredictable enough for cryptographic applications, though its exact quality depends on the OS implementation.

使用Fernet时,有两种方式产生密钥:

(1)让Fernet直接产生

这种方法调用key = Fernet.generate_key()。

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

通过os.urandom(32)产生符合密码学要求的随机数,而后进行base64编码。

(2)自己设定一个密码

如下是个例子:

>>> import base64
>>> import os
>>> from cryptography.fernet import Fernet
>>> from cryptography.hazmat.backends import default_backend
>>> from cryptography.hazmat.primitives import hashes
>>> from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
>>> password = b"password"
>>> salt = os.urandom(16)
>>> kdf = PBKDF2HMAC(
...     algorithm=hashes.SHA256(),
...     length=32,
...     salt=salt,
...     iterations=100000,
...     backend=default_backend()
... )
>>> key = base64.urlsafe_b64encode(kdf.derive(password))
>>> f = Fernet(key)
>>> token = f.encrypt(b"Secret message!")
>>> token
'...'
>>> f.decrypt(token)
'Secret message!

设定一个password,接着使用PBKDF2HMAC。它是个密钥推导函数,通过多次对salt进行hash运算从而产生密钥。该方法被美国政府标准化,并得到广泛采用。以后有时间再进行更加详细的介绍。

通过密钥推导函数,输出32位随机数,使用key = base64.urlsafe_b64encode(kdf.derive(password))产生Fernet使用的密钥。

二、加密和认证功能

这两个功能主要通过 encrypt和_encrypt_from_parts函数实现。

    def _encrypt_from_parts(self, data, current_time, 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()
        basic_parts = (
            b"\x80" + struct.pack(">Q", current_time) + iv + ciphertext
        )
        h = HMAC(self._signing_key, hashes.SHA256(), backend=self._backend)
        h.update(basic_parts)
        hmac = h.finalize()
        return base64.urlsafe_b64encode(basic_parts + hmac)

总结:以上内容就是针对密码库((02)Python密码库Cryptography探究学习---深入理解Fern)详细阐释,如果您觉得有更好的建议可以提供给哪吒游戏网小编,密码库((02)Python密码库Cryptography探究学习---深入理解Fern)部分内容转载自互联网,有帮助可以收藏一下。



上一篇: 密码库(MasterPassword —— 无需数据库的密码管理器)

下一篇: sm职业任务(魔兽世界怀旧服萨满职业任务有哪些类型)

本文标签:
猜你喜欢