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 相关文章推荐
py中的目录与文件判别代码
Jul 16 Python
Python的Flask框架中SQLAlchemy使用时的乱码问题解决
Nov 07 Python
python编码总结(编码类型、格式、转码)
Jul 01 Python
python多进程和多线程究竟谁更快(详解)
May 29 Python
代码详解django中数据库设置
Jan 28 Python
Python3实现定时任务的四种方式
Jun 03 Python
python如何读取bin文件并下发串口
Jul 05 Python
python3中eval函数用法使用简介
Aug 02 Python
python实现知乎高颜值图片爬取
Aug 12 Python
win10环境下配置vscode python开发环境的教程详解
Oct 16 Python
pytorch中交叉熵损失(nn.CrossEntropyLoss())的计算过程详解
Jan 02 Python
python实现三阶魔方还原的示例代码
Apr 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中的登陆login
2007/01/18 PHP
PHP句法规则详解 入门学习
2011/11/09 PHP
php通过前序遍历树实现无需递归的无限极分类
2015/07/10 PHP
10个php函数实用却不常见
2015/10/13 PHP
php实现URL加密解密的方法
2016/11/17 PHP
HTTP头隐藏PHP版本号实现过程解析
2020/12/09 PHP
jquery div 居中技巧应用介绍
2012/11/24 Javascript
table insertRow、deleteRow定义和用法总结
2014/05/14 Javascript
深入理解JavaScript系列(29):设计模式之装饰者模式详解
2015/03/03 Javascript
JavaScript里四舍五入函数round用法实例
2015/04/06 Javascript
JS获取url参数、主域名的方法实例分析
2016/08/03 Javascript
jQuery Mobile和HTML5开发App推广注册页
2016/11/07 Javascript
jQuery animate()实现背景色渐变效果的处理方法【使用jQuery.color.js插件】
2017/03/15 Javascript
微信小程序报错:this.setData is not a function的解决办法
2017/09/27 Javascript
javascript中的隐式调用
2018/02/10 Javascript
深入浅析Vue.js计算属性和侦听器
2018/05/05 Javascript
seajs下require书写约定实例分析
2018/05/16 Javascript
浅谈js闭包理解
2019/04/01 Javascript
Vue 打包体积优化方案小结
2020/05/20 Javascript
Python中isnumeric()方法的使用简介
2015/05/19 Python
Python模块结构与布局操作方法实例分析
2017/07/24 Python
python爬虫面试宝典(常见问题)
2018/03/02 Python
基于Python的微信机器人开发 微信登录和获取好友列表实现解析
2019/08/21 Python
Python+OpenCV实现将图像转换为二进制格式
2020/01/09 Python
python实现连连看游戏
2020/02/14 Python
python模拟哔哩哔哩滑块登入验证的实现
2020/04/24 Python
英国第一的购买便宜玩具和游戏的在线购物网站:Bargain Max
2018/01/24 全球购物
意大利在线药房:Farmacia Loreto Gallo
2019/08/09 全球购物
药品营销策划方案
2014/06/15 职场文书
公务员个人年终总结
2015/02/12 职场文书
工程技术员岗位职责
2015/04/11 职场文书
学校艾滋病宣传活动总结
2015/05/09 职场文书
小学学习委员竞选稿
2015/11/20 职场文书
《妈妈别哭,有我在》读后感3篇
2020/01/13 职场文书
Spring Data JPA使用JPQL与原生SQL进行查询的操作
2021/06/15 Java/Android
opencv用VS2013调试时用Image Watch插件查看图片
2021/07/26 Python