Python3 加密解密技术详解

引言

Python 3 的标准库中没多少用来解决加密的,不过却有用于处理哈希的库。

在这里我们会对其进行一个简单的介绍,但重点会放在两个第三方的软件包:PyCrypto 和 cryptography 上。

我们将学习如何使用这两个库,来加密和解密字符串

哈希

1.哈希简介

使用标准库中的 hashlib 模块可以用来处理安全哈希算法或者消息摘要算法。

这个模块包含了符合 FIPS(美国联邦信息处理标准)的安全哈希算法,例如 SHA1,SHA224,SHA256,SHA384,SHA512 以及 RSA 的 MD5 算法。

当然,Python也支持 adler32 以及 crc32 哈希函数,不过它们在 zlib 模块中。

哈希的最常见的用法是,存储密码的哈希值而非密码本身。这时候使用哈希函数需要稳健一点,否则容易被破解。

另一个常见的用法是,计算一个文件的哈希值,然后将这个文件和它的哈希值分别发送。

接收到文件的人可以计算文件的哈希值,检验是否与接收到的哈希值相符——以此来检验文件是否被篡改。

2.实战示例

  • 创建一个 md5 哈希:

如图所示,我们首先导入hashilb,然后创建一个md5哈希对象的实例。

随后,在示例中添加一个字符串,出现了报错信息。

这是因为计算md5哈希时,必须是用字节形式字符串,正确添加后就可以调用digest函数来得到哈希值了。

  • 十六进制的哈希值

十六进制哈希值可以用以下方法获取:

  • 创建哈希的简单方法

下面我们看一下用这种方法创建一个 sha1 哈希:

可以看到,我们可以同时创建一个哈希实例并且调用其 digest 函数。

然后,我们可以输出这个哈希值看一下。

密钥导出

Python 的标准库对密钥导出支持较弱:hashlib 函数库提供的唯一方法就是 pbkdf2_hmac 函数。

它是 PKCS#5的基于口令的第二个密钥导出函数,并使用 HMAC 作为伪随机函数。

由于它支持“加盐salt”和迭代操作,你可以使用类似的方法来哈希你的密码。

例如,如果你打算使用 SHA-256 加密方法,你将需要至少 16 个字节的“盐”,以及最少 100000 次的迭代操作。

简单来说,“盐”就是随机的数据,被用来加入到哈希的过程中,以加大破解的难度。

这基本可以保护你的密码免受字典和彩虹表rainbow table的攻击。

  • 示例

这里,我们用 SHA256 对一个密码进行哈希,使用了一个糟糕的“盐”,但经过了 100000 次迭代操作。

SHA 实际上并不被推荐用来创建密码的密钥,你应该使用类似scrypt的算法或者使用一个叫 bcrypt 的专门用来哈希密码第三方库。

PyCryptodome

原本是项目分支PyCrytodome 取代了Python中密码学方面最有名的软件包 PyCrypto 。

使用以下命令进行安装PyCrytodome:

  • Linux
  • Windows

如果你遇到了问题,可能是因为你没有安装正确的依赖包(LCTT 译注:如 python-devel),或者你的 Windows 系统需要一个编译器。

DES算法学习

1.DES 算法加密示例

示例步骤如下:

  • 将密钥变量设置为 8 个字符(DES 加密使用的密钥长度为 8 个字节)
  • 创建一个函数pad,来给一个字符串末尾填充空格,直到它的长度是 8 的倍数
  • 创建一个 DES 的实例、需要加密的文本、经过填充处理的文本
  • 尝试着对未经填充处理的文本进行加密,显示ValueError错误
  • 过填充处理的文本进行加密,得到加密的字符串

2.DES解密示例

解密非常容易,调用des对象的decrypt方法就可以得到原来的byte类型字符串了。

下一个任务是学习如何用 RSA 算法加密和解密一个文件。

RSA算法学习

要使用 RSA 算法加密数据,必须拥有访问 RAS 公钥和私钥的权限,否则你需要生成一组自己的密钥对。

在这个例子中,我们将生成自己的密钥对。

1.在 Python 解释器中创建 RSA 密钥:

  • 从 Crypto.PublicKey 包中导入 RSA,创建一个密码
  • 生成 2048 位的 RSA 密钥
  • 调用 RSA 密钥实例的 exportKey 方法,传入密码、使用的 PKCS 标准以及加密方案这三个参数。
  • 将私钥写入磁盘的文件。
  • 使用方法链调用publickey 和 exportKey 方法生成公钥,写入磁盘上的文件。

2.加密文件

有了私钥和公钥之后,我们就可以加密一些数据,并写入文件了。

  • 导入 PyCryptodome 包
  • 打开一个文件用于写入数据
  • 导入公钥赋给一个变量,创建一个 16 字节的会话密钥。例中使用混合加密方法,即 PKCS#1 OAEP,也就是最优非对称加密填充
  • 创建 AES 加密,然后加密数据,得到加密的文本和消息认证码
  • 将随机数、消息认证码和加密的文本写入文件

这里的随机数通常是真随机或伪随机数,只是用来进行密码通信的。对于 AES 加密,其密钥长度最少是 16 个字节。

3.解密示例

  • 以二进制模式读取加密文件
  • 导入私钥。注意,导入私钥时,需要提供密码
  • 文件中读取加密的会话密钥、 16 字节的随机数、16 字节的消息认证码和其他加密数据
  • 解密出会话密钥,重新创建 AES 密钥
  • 解密出数据

接下来就是cryptography包的学习。

cryptography包

cryptography能够创建简单安全、易于使用的加密方案。如果有需要的话,你也可以使用一些底层的密码学基元。

1.安装

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

如果安装成功,我们就可以试着加密一些文本了。

建议使用 Fernet 对称加密算法,它保证了加密信息在不知道密码的情况下不能被篡改或读取。Fernet 还通过 MultiFernet 支持密钥轮换。

2.示例

下面看一个简单的例子:

  • 导入 Fernet
  • 生成一个密钥,它是一个随机的字节串。
  • 使用这个密钥生成 Fernet 密码
  • 现在我们有了用来加密和解密消息的密码
  • 创建一个消息,然后使用 encrypt 方法对它加密
  • 输出出加密的文本
  • 调用 decrypt 方法,并传入加密的文本作为参数
  • 得到了消息字节串形式的纯文本,完成解密

小结

本文浅显地介绍了 PyCryptodome 和 cryptography 这两个包的使用,即关于如何加密解密字符串和文件的简述。

如果想要获取更多的更深度的内容,可以阅读官方文档或进行实战练习。

原文发布于微信公众号 - 马哥Linux运维(magedu-Linux)

原文发表时间:2017-03-11

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏窗户

python使用rsa库做公钥解密(网上别处找不到)

  使用RSA公钥解密,用openssl命令就是openssl rsautl -verify -in cipher_text -inkey public.pem...

4969
来自专栏三好码农的三亩自留地

浅析 RxJava 2.x 线程调度

为了说明原理,排除干扰,这里用了最简单的逻辑。产生一个字符串“Hello rxJava”, 然后在监听中打印log,subscribeOn(Schedulers...

1001
来自专栏图像识别与深度学习

encyption&decyption

2639
来自专栏Java技术栈

JSON Web Token (JWT)生成Token及解密实战。

昨天讲解了JWT的介绍、应用场景、优点及注意事项等,今天来个JWT具体的使用实践吧。 从JWT官网支持的类库来看,jjwt是Java支持的算法中最全的,推荐使用...

9215
来自专栏Android开发与分享

【Android】RxJava的使用(一)基本用法

3537
来自专栏BaronTalk

RxJava系列二(基本概念及使用介绍)

前言 上一篇的示例代码中大家一定发现了Observable这个类。从纯Java的观点看,Observable类源自于经典的观察者模式。RxJava的异步实现正是...

36910
来自专栏程序员Gank

【译】在正确的线程上观察

尽管很多人了解RxJava的基本逻辑,但是在Observable链和操作符究竟运行在哪个线程,仍然会有许多困惑。

1142
来自专栏技术换美食换不换

TOB服务部署安全模块

1484
来自专栏安恒网络空间安全讲武堂

jarvisoj-Crypto

jarvisoj-Crypto Medium RSA 题目到手后给了一个公钥和一个密文 ? ? 我们对这个公钥提取信息: ? 可以得到 N = 0xC2636A...

1.2K6
来自专栏JavaEE

spring和springboot中加密连接数据库的信息前言:一、spring中加密连接数据库的信息:二、springboot项目中加密数据库连接信息:总结:

在实际开发中,一些关键的信息肯定是要加密的,否则就太不安全了。比如连接数据库的用户名和密码,一般就需要加密。接下来就看看spring项目和spring boot...

2363

扫码关注云+社区

领取腾讯云代金券