Python3对称加密算法AES、DES3实例详解


Posted in Python onDecember 06, 2018

本文实例讲述了Python3对称加密算法AES、DES3。分享给大家供大家参考,具体如下:

python3.6此库安装方式,需要pip3 install pycryptodome。

如有site-packages中存在crypto、pycrypto,在pip之前,需要pip3 uninstall cryptopip3 uninstall pycrypto,否则无法安装成功。

C:\WINDOWS\system32>pip3 install pycryptodome
Collecting pycryptodome
  Downloading https://files.pythonhosted.org/packages/0f/5d/a429a53eacae3e13143248c3868c76985bcd0d75858bd4c25b574e51bd4d/pycryptodome-3.6.3-cp36-cp36m-win_amd64.whl (7.9MB)
    100% |????????????????????????????????| 7.9MB 111kB/s
Installing collected packages: pycryptodome
Successfully installed pycryptodome-3.6.3

这里顺带说一下pycrypto,这个库已经有很久没有人维护了,如果需要安装此库,需要先安装 VC++ build tools

然后将 ~\BuildTools\VC\Tools\MSVC\14.15.26726\include 目录下的 stdint.h 拷贝到 C:\Program Files (x86)\Windows Kits\10\Include\10.0.17134.0\ucrt 下。(Win10 需管理员权限)

接着将同目录下的 inttypes.h 中的 #include <stdint.h> (第十四行),改成 #include "stdint.h"

然后使用 pip3 install pycrypto,就能直接安装了。

注:如果不是业务需要,请尽可能使用 pycryptodome。

AES:

import Crypto.Cipher.AES
import Crypto.Random
import base64
import binascii
def auto_fill(x):
  if len(x) <= 32:
    while len(x) not in [16, 24, 32]:
      x += " "
    return x.encode()
  else:
    raise "密钥长度不能大于32位!"
key = "asd"
content = "abcdefg1234567"
x = Crypto.Cipher.AES.new(auto_fill(key), Crypto.Cipher.AES.MODE_ECB)
a = base64.encodebytes(x.encrypt(auto_fill(content)))
b = x.decrypt(base64.decodebytes(a))
print(a)
print(b)
a = binascii.b2a_base64(x.encrypt(auto_fill(content)))
b = x.decrypt(binascii.a2b_base64(a))
print(a)
print(b)
key = "dsa"
iv = Crypto.Random.new().read(16)  # 向量,必须为16字节
content = "1234567abcdefg"
y = Crypto.Cipher.AES.new(auto_fill(key), Crypto.Cipher.AES.MODE_CBC, iv)
c = binascii.b2a_base64(y.encrypt(auto_fill(content)))
z = Crypto.Cipher.AES.new(auto_fill(key), Crypto.Cipher.AES.MODE_CBC, iv)
d = z.decrypt(binascii.a2b_base64(c))
print(c)
print(d)

运行结果:

b'jr/EIUp32kLHc3ypZZ1cyg==\n'
b'abcdefg1234567  '
b'jr/EIUp32kLHc3ypZZ1cyg==\n'
b'abcdefg1234567  '
b'j+Ul9KQd0HnuiHW3z9tD7A==\n'
b'1234567abcdefg  '

DES3:

import Crypto.Cipher.DES3
import base64
import binascii
def auto_fill(x):
  if len(x) > 24:
    raise "密钥长度不能大于等于24位!"
  else:
    while len(x) < 16:
      x += " "
    return x.encode()
key = "asd"
content = "abcdefg1234567"
x = Crypto.Cipher.DES3.new(auto_fill(key), Crypto.Cipher.DES3.MODE_ECB)
a = base64.encodebytes(x.encrypt(auto_fill(content)))
print(a)
b = x.decrypt(base64.decodebytes(a))
print(b)
a = binascii.b2a_base64(x.encrypt(auto_fill(content)))
b = x.decrypt(binascii.a2b_base64(a))
print(a)
print(b)

运行结果:

b'/ee3NFKeNqEk/qMNd1mjog==\n'
b'abcdefg1234567  '
b'/ee3NFKeNqEk/qMNd1mjog==\n'
b'abcdefg1234567  '

附:AES的工厂模式封装Cipher_AES.py(封装Crypto.Cipher.AES)

'''
Created on 2018年7月7日
@author: ray
'''
import Crypto.Cipher.AES
import Crypto.Random
import base64
import binascii
class Cipher_AES:
  pad_default = lambda x, y: x + (y - len(x) % y) * " ".encode("utf-8")
  unpad_default = lambda x: x.rstrip()
  pad_user_defined = lambda x, y, z: x + (y - len(x) % y) * z.encode("utf-8")
  unpad_user_defined = lambda x, z: x.rstrip(z)
  pad_pkcs5 = lambda x, y: x + (y - len(x) % y) * chr(y - len(x) % y).encode("utf-8")
  unpad_pkcs5 = lambda x: x[:-ord(x[-1])]
  def __init__(self, key="abcdefgh12345678", iv=Crypto.Random.new().read(Crypto.Cipher.AES.block_size)):
    self.__key = key
    self.__iv = iv
  def set_key(self, key):
    self.__key = key
  def get_key(self):
    return self.__key
  def set_iv(self, iv):
    self.__iv = iv
  def get_iv(self):
    return self.__iv
  def Cipher_MODE_ECB(self):
    self.__x = Crypto.Cipher.AES.new(self.__key.encode("utf-8"), Crypto.Cipher.AES.MODE_ECB)
  def Cipher_MODE_CBC(self):
    self.__x = Crypto.Cipher.AES.new(self.__key.encode("utf-8"), Crypto.Cipher.AES.MODE_CBC, self.__iv.encode("utf-8"))
  def encrypt(self, text, cipher_method, pad_method="", code_method=""):
    if cipher_method.upper() == "MODE_ECB":
      self.Cipher_MODE_ECB()
    elif cipher_method.upper() == "MODE_CBC":
      self.Cipher_MODE_CBC()
    cipher_text = b"".join([self.__x.encrypt(i) for i in self.text_verify(text.encode("utf-8"), pad_method)])
    if code_method.lower() == "base64":
      return base64.encodebytes(cipher_text).decode("utf-8").rstrip()
    elif code_method.lower() == "hex":
      return binascii.b2a_hex(cipher_text).decode("utf-8").rstrip()
    else:
      return cipher_text.decode("utf-8").rstrip()
  def decrypt(self, cipher_text, cipher_method, pad_method="", code_method=""):
    if cipher_method.upper() == "MODE_ECB":
      self.Cipher_MODE_ECB()
    elif cipher_method.upper() == "MODE_CBC":
      self.Cipher_MODE_CBC()
    if code_method.lower() == "base64":
      cipher_text = base64.decodebytes(cipher_text.encode("utf-8"))
    elif code_method.lower() == "hex":
      cipher_text = binascii.a2b_hex(cipher_text.encode("utf-8"))
    else:
      cipher_text = cipher_text.encode("utf-8")
    return self.unpad_method(self.__x.decrypt(cipher_text).decode("utf-8"), pad_method)
  def text_verify(self, text, method):
    while len(text) > len(self.__key):
      text_slice = text[:len(self.__key)]
      text = text[len(self.__key):]
      yield text_slice
    else:
      if len(text) == len(self.__key):
        yield text
      else:
        yield self.pad_method(text, method)
  def pad_method(self, text, method):
    if method == "":
      return Cipher_AES.pad_default(text, len(self.__key))
    elif method == "PKCS5Padding":
      return Cipher_AES.pad_pkcs5(text, len(self.__key))
    else:
      return Cipher_AES.pad_user_defined(text, len(self.__key), method)
  def unpad_method(self, text, method):
    if method == "":
      return Cipher_AES.unpad_default(text)
    elif method == "PKCS5Padding":
      return Cipher_AES.unpad_pkcs5(text)
    else:
      return Cipher_AES.unpad_user_defined(text, method)

使用方法:

        加密:Cipher_AES(key [, iv]).encrypt(text, cipher_method [, pad_method [, code_method]])

        解密:Cipher_AES(key [, iv]).decrypt(cipher_text, cipher_method [, pad_method [, code_method]])

key:密钥(长度必须为16、24、32)

iv:向量(长度与密钥一致,ECB模式不需要)

text:明文(需要加密的内容)

cipher_text:密文(需要解密的内容)

cipher_method:加密方法,目前只有"MODE_ECB"、"MODE_CBC"两种

pad_method:填充方式,解决 Java 问题选用"PKCS5Padding"

code_method:编码方式,目前只有"base64"、"hex"两种

来段调用封装类 Cipher_AES 的 demo_Cipher_AES.py,方便大家理解:

import Cipher_AES
key = "qwedsazxc123321a"
iv = key[::-1]
text = "我爱小姐姐,可小姐姐不爱我 - -"
cipher_method = "MODE_CBC"
pad_method = "PKCS5Padding"
code_method = "base64"
cipher_text = Cipher_AES(key, iv).encrypt(text, cipher_method, pad_method, code_method)
print(cipher_text)
text = Cipher_AES(key, iv).decrypt(cipher_text, cipher_method, pad_method, code_method)
print(text)
'''
运行结果:
uxhf+MoSko4xa+jGOyzJvYH9n5NvrCwEHbwm/A977CmGqzg+fYE0GeL5/M5v9O1o
我爱小姐姐,可小姐姐不爱我 - -
'''
Python 相关文章推荐
Python中的自定义函数学习笔记
Sep 23 Python
Python的Flask框架中web表单的教程
Apr 20 Python
Python中Collections模块的Counter容器类使用教程
May 31 Python
TF-IDF与余弦相似性的应用(二) 找出相似文章
Dec 21 Python
解决python中无法自动补全代码的问题
Dec 04 Python
python random从集合中随机选择元素的方法
Jan 23 Python
通过python实现随机交换礼物程序详解
Jul 10 Python
win10子系统python开发环境准备及kenlm和nltk的使用教程
Oct 14 Python
Python astype(np.float)函数使用方法解析
Jun 08 Python
使用Selenium实现微博爬虫(预登录、展开全文、翻页)
Apr 13 Python
Pygame Rect区域位置的使用(图文)
Nov 17 Python
Python 读取千万级数据自动写入 MySQL 数据库
Jun 28 Python
Python http接口自动化测试框架实现方法示例
Dec 06 #Python
python的常用模块之collections模块详解
Dec 06 #Python
Django管理员账号和密码忘记的完美解决方法
Dec 06 #Python
Python操作json的方法实例分析
Dec 06 #Python
Python多线程应用于自动化测试操作示例
Dec 06 #Python
Python实现多属性排序的方法
Dec 05 #Python
python通过ffmgep从视频中抽帧的方法
Dec 05 #Python
You might like
用php制作简单分页(从数据库读取记录)的方法详解
2013/05/04 PHP
探讨:php中在foreach中使用foreach ($arr as &amp;$value) 这种类型的解释
2013/06/24 PHP
PHP扩展模块Pecl、Pear以及Perl的区别
2014/04/09 PHP
PHP 面向对象程序设计(oop)学习笔记 (二) - 静态变量的属性和方法及延迟绑定
2014/06/12 PHP
CI框架入门示例之数据库取数据完整实现方法
2014/11/05 PHP
搜索附近的人PHP实现代码
2018/02/11 PHP
JavaScript Event学习第九章 鼠标事件
2010/02/08 Javascript
node.js中的fs.link方法使用说明
2014/12/15 Javascript
JS实现针对给定时间的倒计时功能示例
2017/04/11 Javascript
详解Vuex中mapState的具体用法
2017/09/28 Javascript
使用Vue完成一个简单的todolist的方法
2017/12/01 Javascript
bootstrap select2插件用ajax来获取和显示数据的实例
2018/08/09 Javascript
Vue Cli3 打包配置并自动忽略console.log语句的方法
2020/04/23 Javascript
基于JQuery实现页面定时弹出广告
2020/05/08 jQuery
[00:12]2018DOTA2亚洲邀请赛 sylar表现SOLO技艺
2018/04/06 DOTA
python获取指定时间差的时间实例详解
2017/04/11 Python
解决python3中cv2读取中文路径的问题
2018/12/05 Python
python实现文本界面网络聊天室
2018/12/12 Python
Python将列表数据写入文件(txt, csv,excel)
2019/04/03 Python
Pycharm打开已有项目配置python环境的方法
2020/07/03 Python
Python3.7安装pyaudio教程解析
2020/07/24 Python
Python3爬虫中识别图形验证码的实例讲解
2020/07/30 Python
查找廉价航班和发现新目的地:Kiwi.com
2019/02/25 全球购物
大学生毕业自我鉴定
2013/11/06 职场文书
会计顶岗实习心得
2014/01/25 职场文书
竞聘上岗演讲稿
2014/05/16 职场文书
电子商务专业应届生求职信
2014/05/28 职场文书
工商管理自荐书
2014/07/06 职场文书
群众路线对照检查剖析材料
2014/10/09 职场文书
入党积极分子自我批评思想汇报
2014/10/10 职场文书
安全第一课观后感
2015/06/18 职场文书
3招让你摆脱即兴讲话冷场尴尬
2019/08/08 职场文书
python 对图片进行简单的处理
2021/06/23 Python
使用jpa之动态插入与修改(重写save)
2021/11/23 Java/Android
Python turtle编写简单的球类小游戏
2022/03/31 Python
Golang 链表的学习和使用
2022/04/19 Golang