Python3中加密与解密详解


当前第2页 返回上一页

接下来,我们通过 RSA 密钥实例的 publickey 方法创建我们的公钥。我们使用方法链调用 publickey 和 exportKey 方法生成公钥,同样将它写入磁盘上的文件。

加密文件

有了私钥和公钥之后,我们就可以加密一些数据,并写入文件了。这里有个比较标准的例子:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

from Crypto.PublicKey import RSA

from Crypto.Random import get_random_bytes

from Crypto.Cipher import AES, PKCS1_OAEP

with open('/path/to/encrypted_data.bin', 'wb') as out_file:

    recipient_key = RSA.import_key(

        open('/path_to_public_key/my_rsa_public.pem').read())

    session_key = get_random_bytes(16)

    cipher_rsa = PKCS1_OAEP.new(recipient_key)

    out_file.write(cipher_rsa.encrypt(session_key))

    cipher_aes = AES.new(session_key, AES.MODE_EAX)

    data = b'blah blah blah Python blah blah'

    ciphertext, tag = cipher_aes.encrypt_and_digest(data)

    out_file.write(cipher_aes.nonce)

    out_file.write(tag)

    out_file.write(ciphertext)

代码的前三行导入 PyCryptodome 包。然后我们打开一个文件用于写入数据。接着我们导入公钥赋给一个变量,创建一个 16 字节的会话密钥。在这个例子中,我们将使用混合加密方法,即 PKCS#1 OAEP ,也就是最优非对称加密填充。这允许我们向文件中写入任意长度的数据。接着我们创建 AES 加密,要加密的数据,然后加密数据。我们将得到加密的文本和消息认证码。最后,我们将随机数,消息认证码和加密的文本写入文件。

顺便提一下,随机数通常是真随机或伪随机数,只是用来进行密码通信的。对于 AES 加密,其密钥长度最少是 16 个字节。随意用一个你喜欢的编辑器试着打开这个被加密的文件,你应该只能看到乱码。

现在让我们学习如何解密我们的数据。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

from Crypto.PublicKey import RSA

from Crypto.Cipher import AES, PKCS1_OAEP

code = 'nooneknows'

with open('/path/to/encrypted_data.bin', 'rb') as fobj:

    private_key = RSA.import_key(

        open('/path_to_private_key/my_rsa_key.pem').read(),

        passphrase=code)

    enc_session_key, nonce, tag, ciphertext = [ fobj.read(x)

                                                for x in (private_key.size_in_bytes(),

                                                16, 16, -1) ]

    cipher_rsa = PKCS1_OAEP.new(private_key)

    session_key = cipher_rsa.decrypt(enc_session_key)

    cipher_aes = AES.new(session_key, AES.MODE_EAX, nonce)

    data = cipher_aes.decrypt_and_verify(ciphertext, tag)

print(data)

如果你认真看了上一个例子,这段代码应该很容易解析。在这里,我们先以二进制模式读取我们的加密文件,然后导入私钥。注意,当你导入私钥时,需要提供一个密码,否则会出现错误。然后,我们文件中读取数据,首先是加密的会话密钥,然后是 16 字节的随机数和 16 字节的消息认证码,最后是剩下的加密的数据。

接下来我们需要解密出会话密钥,重新创建 AES 密钥,然后解密出数据。

你还可以用 PyCryptodome 库做更多的事。不过我们要接着讨论在 Python 中还可以用什么来满足我们加密解密的需求。

cryptography 包

cryptography 的目标是成为“人类易于使用的密码学包cryptography for humans”,就像 requests 是“人类易于使用的 HTTP 库HTTP for Humans”一样。这个想法使你能够创建简单安全、易于使用的加密方案。如果有需要的话,你也可以使用一些底层的密码学基元,但这也需要你知道更多的细节,否则创建的东西将是不安全的。

如果你使用的 Python 版本是 3.5, 你可以使用 pip 安装,如下:

1

pip install cryptography

你会看到 cryptography 包还安装了一些依赖包(LCTT 译注:如 libopenssl-devel)。如果安装都顺利,我们就可以试着加密一些文本了。让我们使用 Fernet 对称加密算法,它保证了你加密的任何信息在不知道密码的情况下不能被篡改或读取。Fernet 还通过 MultiFernet 支持密钥轮换。下面让我们看一个简单的例子:

1

2

3

4

5

6

7

8

9

10

11

12

13

>>> from cryptography.fernet import Fernet

>>> cipher_key = Fernet.generate_key()

>>> cipher_key

b'APM1JDVgT8WDGOWBgQv6EIhvxl4vDYvUnVdg-Vjdt0o='

>>> cipher = Fernet(cipher_key)

>>> text = b'My super secret message'

>>> encrypted_text = cipher.encrypt(text)

>>> encrypted_text

(b'gAAAAABXOnV86aeUGADA6mTe9xEL92y_m0_TlC9vcqaF6NzHqRKkjEqh4d21PInEP3C9HuiUkS9f'

 b'6bdHsSlRiCNWbSkPuRd_62zfEv3eaZjJvLAm3omnya8=')

>>> decrypted_text = cipher.decrypt(encrypted_text)

>>> decrypted_text

b'My super secret message'

首先我们需要导入 Fernet,然后生成一个密钥。我们输出密钥看看它是什么样儿。如你所见,它是一个随机的字节串。如果你愿意的话,可以试着多运行 generate_key 方法几次,生成的密钥会是不同的。然后我们使用这个密钥生成 Fernet 密码实例。

现在我们有了用来加密和解密消息的密码。下一步是创建一个需要加密的消息,然后使用 encrypt 方法对它加密。我打印出加密的文本,然后你可以看到你再也读不懂它了。为了解密出我们的秘密消息,我们只需调用 decrypt 方法,并传入加密的文本作为参数。结果就是我们得到了消息字节串形式的纯文本。

小结

这一章仅仅浅显地介绍了 PyCryptodome 和 cryptography 这两个包的使用。不过这也确实给了你一个关于如何加密解密字符串和文件的简述。请务必阅读文档,做做实验,看看还能做些什么!

以上就是Python3中加密与解密详解的详细内容,更多文章请关注木庄网络博客!!

返回前面的内容

相关阅读 >>

Python如何设置曲线样式

Python和c区别

Python类变量和实例变量的区别

Python怎么升序和降序排序

py文件怎么执行

Python验证码识别教程之利用投影法、连通域法分割图片

用turtle画个单身狗送给自己~

ubuntu怎么安装Python

Python之中正则表达式详解(实例分析)

什么是神经网络?

更多相关阅读请进入《Python》频道 >>




打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,您说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

分享从这里开始,精彩与您同在

评论

管理员已关闭评论功能...